Введение

Процесс планирования программных решений

Проектирование программного обеспечения — это процесс концептуализации работы программной системы до её реализации или модификации. Проектирование программного обеспечения также относится к непосредственному результату этого процесса — представлению о том, как программное обеспечение будет работать, которое включает в себя как проектную документацию, так и неофициальные концепции. Проектирование программного обеспечения обычно определяется целями для создаваемой системы и включает решение задач и планирование, охватывающее как высокоуровневую архитектуру программного обеспечения, так и проектирование низкоуровневых компонентов и алгоритмов. В контексте каскадной модели разработки, проектирование программного обеспечения следует за спецификацией требований и предшествует кодированию.

Общий процесс

Процесс проектирования позволяет разработчику моделировать различные аспекты программной системы до её создания. Креативность, предыдущий опыт, понимание того, что составляет "качественное" программное обеспечение, и стремление к качеству – факторы, определяющие успех компетентного проектирования. Однако процесс проектирования не всегда является однозначным. Модель проектирования программного обеспечения можно сравнить с архитектурным планом дома. Планы высокого уровня отражают общую картину дома (например, трехмерная визуализация дома). Планы нижнего уровня предоставляют инструкции для реализации каждой детали (например, схема прокладки сантехники). Аналогично, модель проектирования программного обеспечения предоставляет различные представления о предлагаемом программном решении.

Стоимость

Документация по проектированию программного обеспечения может быть рассмотрена или представлена для корректировки ограничений, спецификаций и даже требований до начала кодирования. Перепроектирование может потребоваться после анализа запрограммированной симуляции или прототипа. Возможно проектирование программного обеспечения непосредственно в процессе кодирования, без предварительного плана или анализа требований, однако для более сложных проектов это менее целесообразно. Разработка отдельного проекта до кодирования позволяет дизайнерам различных специальностей и экспертам в предметной области сотрудничать с программистами для создания полезного и технически надежного программного обеспечения.

Анализ требований

Одним из компонентов проектирования программного обеспечения является анализ требований к программному обеспечению (SRA). SRA – это часть процесса разработки программного обеспечения, определяющая спецификации, используемые в разработке программного обеспечения. Результатом анализа являются более мелкие, конкретные задачи для решения. В отличие от этого, проектирование фокусируется на функциональных возможностях, поэтому для одной и той же проблемы может существовать несколько вариантов проектирования. В зависимости от среды, проектирование может варьироваться, будь то создание на основе надежных фреймворков или реализация с использованием подходящих шаблонов проектирования.

Принципы проектирования

Основные принципы проектирования позволяют инженеру программного обеспечения ориентироваться в процессе проектирования. Дэвис предлагает набор принципов для проектирования программного обеспечения, которые были адаптированы и расширены в следующем списке:
Процесс проектирования не должен страдать от "туннельного мышления". Хороший разработчик должен рассматривать альтернативные подходы, оценивая каждый из них на основе требований задачи и доступных ресурсов. Проектирование должно быть прослеживаемым до модели анализа. Поскольку один элемент модели проектирования часто может быть связан с несколькими требованиями, необходимо предусмотреть механизмы отслеживания того, как требования реализованы в модели проектирования. Проектирование не должно изобретать велосипед. Системы создаются с использованием набора шаблонов проектирования, многие из которых, вероятно, уже известны. Эти шаблоны всегда следует выбирать вместо повторного изобретения. Время ограничено, ресурсы ограничены; время проектирования следует инвестировать в представление (действительно новых) идей путем интеграции уже существующих шаблонов (когда это применимо). Проектирование должно "минимизировать интеллектуальную дистанцию" между программным обеспечением и проблемой, как она существует в реальном мире. То есть, структура программного обеспечения должна, по возможности, отражать структуру предметной области. Проектирование должно быть единообразным и интегрированным. Проект является единообразным, если он выглядит целостным и последовательным. Для достижения этого результата правила стиля и форматирования должны быть определены для команды проектирования до начала работы. Проект является интегрированным, если уделяется внимание определению интерфейсов между компонентами проекта. Проектирование должно быть структурировано с учетом возможности изменений. Концепции проектирования, обсуждаемые в следующем разделе, позволяют достичь этого принципа. Проектирование должно быть структурировано таким образом, чтобы оно корректно обрабатывало ошибки, даже при возникновении аномальных данных, событий или условий эксплуатации. Хорошо спроектированное программное обеспечение никогда не должно аварийно завершать работу; оно должно быть разработано с учетом необычных обстоятельств, и в случае необходимости прекращения обработки, оно должно делать это изящно. Проектирование – это не кодирование, а кодирование – это не проектирование. Даже при создании детализированных процедурных проектов для компонентов программы, уровень абстракции модели проектирования выше, чем у исходного кода. Единственные решения по проектированию, принимаемые на уровне кодирования, должны касаться небольших деталей реализации, необходимых для кодирования процедурного проекта. Качество проектирования должно оцениваться в процессе его создания, а не постфактум. Существует множество концепций и метрик проектирования, которые могут помочь разработчику в оценке качества на протяжении всего процесса разработки. Проект следует проверять для минимизации концептуальных (семантических) ошибок. Иногда при проверке проекта возникает тенденция сосредотачиваться на мелочах, упуская общую картину. Команда проектирования должна убедиться, что основные концептуальные элементы проекта (пропуски, неоднозначность, несогласованность) были рассмотрены, прежде чем беспокоиться о синтаксисе модели проектирования.

Концепции проектирования

Концепции проектирования предоставляют дизайнеру основу, на которой могут быть применены более сложные методы. Сформировался набор концепций проектирования, включающий:

Абстракция – это процесс или результат обобщения путем уменьшения информационного содержания концепции или наблюдаемого явления, как правило, для сохранения только информации, релевантной для конкретной цели. Это представление существенных характеристик без включения фоновых деталей или объяснений.

Уточнение – это процесс детализации. Иерархия разрабатывается путем последовательного разложения макроскопического описания функции, пока не будут достигнуты операторы языка программирования. На каждом шаге одна или несколько инструкций программы декомпозируются на более детальные инструкции. Абстракция и уточнение – взаимодополняющие концепции.

Модульность – архитектура программного обеспечения разделяется на компоненты, называемые модулями.

Архитектура программного обеспечения – это общая структура программного обеспечения и способы, которыми эта структура обеспечивает концептуальную целостность системы. Хорошая архитектура программного обеспечения обеспечивает высокую отдачу от инвестиций в отношении желаемого результата проекта, например, с точки зрения производительности, качества, сроков и стоимости.

Иерархия управления – структура программы, представляющая организацию компонента программы и подразумевающая иерархию управления.

Структурное разделение – структура программы может быть разделена по горизонтали и по вертикали. Горизонтальное разделение определяет отдельные ветви модульной иерархии для каждой основной функции программы. Вертикальное разделение предполагает, что управление и выполнение должны быть распределены сверху вниз по структуре программы.

Структура данных – это представление логических связей между отдельными элементами данных.

Программная процедура – фокусируется на обработке каждого модуля по отдельности.

Сокрытие информации – модули должны быть специфицированы и разработаны таким образом, чтобы информация, содержащаяся в модуле, была недоступна другим модулям, которые в ней не нуждаются.

В своей объектной модели Грейди Буч упоминает абстракцию, инкапсуляцию, модулизацию и иерархию как фундаментальные принципы проектирования программного обеспечения. Иногда для обозначения этих четырех основных принципов используется аббревиатура PHAME (Principles of Hierarchy, Abstraction, Modularisation, and Encapsulation).

Относительно конструкции

При разработке программного обеспечения необходимо учитывать множество аспектов. Важность каждого из этих аспектов должна отражать цели и ожидания, которым должно соответствовать программное обеспечение. Некоторые из этих аспектов:

Совместимость – способность программного обеспечения работать с другими продуктами, предназначенными для взаимодействия. Например, программное обеспечение может быть обратно совместимо со своей более ранней версией.

Расширяемость – возможность добавления новых функций в программное обеспечение без внесения существенных изменений в базовую архитектуру.

Модульность – результирующее программное обеспечение состоит из чётко определённых, независимых компонентов, что повышает удобство его поддержки. Эти компоненты могут быть реализованы и протестированы изолированно перед интеграцией в целевую программную систему, что позволяет разделить работу в проекте разработки.

Отказоустойчивость – способность программного обеспечения противостоять сбоям компонентов и восстанавливаться после них.

Поддерживаемость – мера легкости внесения исправлений ошибок или функциональных изменений. Высокая поддерживаемость может быть следствием модульности и расширяемости.

Надёжность (долговечность программного обеспечения) – способность программного обеспечения выполнять требуемую функцию в заданных условиях в течение определённого периода времени.

Повторное использование – возможность использования части или всех аспектов существующего программного обеспечения в других проектах с минимальными или отсутствующими изменениями.

Устойчивость – способность программного обеспечения работать в условиях повышенной нагрузки или обрабатывать непредсказуемые или недопустимые входные данные. Например, оно может быть разработано с учётом устойчивости к нехватке памяти.

Безопасность – способность программного обеспечения противостоять и отражать враждебные действия и воздействия.

Удобство использования – пользовательский интерфейс программного обеспечения должен быть удобен для целевой аудитории. Значения параметров по умолчанию должны быть выбраны таким образом, чтобы они подходили большинству пользователей.

Производительность – программное обеспечение должно выполнять свои задачи за время, приемлемое для пользователя, и не требовать чрезмерного расхода памяти.

Переносимость – программное обеспечение должно быть применимо в различных условиях и средах.

Масштабируемость – способность программного обеспечения эффективно адаптироваться к увеличению объёма данных, добавлению новых функций или росту числа пользователей.

Конструктивные шаблоны

Разработчик программного обеспечения может обнаружить аспект проектирования, который уже рассматривался и, возможно, даже был решён другими ранее. Шаблон или образец, описывающий решение распространённой проблемы, известен как шаблон проектирования. Повторное использование таких шаблонов может повысить скорость разработки программного обеспечения.

Код как проект

Трудность использования термина "дизайн" по отношению к программному обеспечению заключается в том, что в определенном смысле исходный код программы и есть проект той программы, которую он создает. В той мере, в которой это справедливо, "проектирование программного обеспечения" относится к проектированию проекта. Эдсгер В. Дейкстра назвал это наслоение семантических уровней "радикальной новизной" компьютерного программирования, а Дональд Кнут, опираясь на свой опыт написания TeX, описал бесплодность попыток спроектировать программу до её реализации.