Проектирование программного обеспечения
Проектирование программного обеспечения (англ. software design) — это процесс концептуализации того, как будет работать программная система, до её реализации или модификации[1]. Под проектированием программного обеспечения также понимается непосредственный результат такого процесса — концепции того, как будет работать программа. Эти концепции могут быть формально документированы или же поддерживаться неофициально, в том числе посредством устной передачи.
Процесс проектирования позволяет моделировать различные аспекты программной системы до её создания с целью повышения эффективности последующей разработки кода. Ключевыми факторами успешного проектирования являются креативность, прошлый опыт, понимание критериев «качественного» программного обеспечения и нацеленность на качество.
Проект программного обеспечения можно сравнить с архитектурным планом дома. Общие планы отображают всю конструкцию (например, трёхмерное изображение дома), а детальные планы описывают отдельные элементы (например, схему водопровода). Аналогично, модель проектирования программного обеспечения предоставляет различные представления предлагаемых решений.
Место в процессе разработки
В терминах каскадной модели разработки, проектирование программного обеспечения является стадией, следующей за анализом требований и предшествующей программированию[2]. Анализ требований определяет, что должна делать система, не затрагивая вопрос как это реализовать, поэтому возможно множество вариантов проектов, удовлетворяющих исходным требованиям. Проектирование может выполняться прямо в процессе программирования, без плана или анализа требований[3], однако для сложных проектов это менее осуществимо. Завершённое до программирования проектирование позволяет взаимодействовать специалистам из разных областей с программистами для создания функционального и технически обоснованного программного обеспечения.
Иногда для поиска оптимального решения создаются модели или прототипы системы.
Код как форма проектирования
Одно из затруднений, связанных с термином «проектирование» в программировании, заключается в том, что этот процесс применяется на разных уровнях абстракции — от архитектуры программного обеспечения до отдельных компонентов, функций и алгоритмов. На высоких уровнях абстракции процесс проектирования может быть достаточно формальным, тогда как на низких уровнях результатом проектирования становится непосредственно программный код. В таком случае проектирование программного обеспечения становится проектированием самого процесса проектирования. Эдсгер Дейкстра называл такой уровневый подход к организации смысловых уровней «радикальной новизной программирования»[4], а Дональд Кнут, используя свой опыт написания TeX, отмечал бесполезность попытки полностью спроектировать программу до её реализации:
TeX был бы полным провалом, если бы я только задал его спецификации и не участвовал бы в его непосредственной реализации. Процесс реализации постоянно приводил меня к неожиданным вопросам и новым пониманиям, как можно улучшить исходные спецификации[5].
Артефакты проектирования
Процесс проектирования может сопровождаться созданием артефактов проектной документации, таких как блок-схема, вариант использования, псевдокод, модель в унифицированном языке моделирования (UML) и других концептуальных моделях. Для ориентированных на пользователя систем проектирование включает проектирование пользовательского опыта, что может приводить к построению раскадровок для уточнения спецификаций. Документация может пересматриваться с целью корректировки ограничений, спецификаций и даже требований до этапа кодирования.
Итеративное проектирование
Программные системы по природе своей связаны с неопределённостью, а размер компонентов способен существенно влиять на работу системы как положительно, так и отрицательно. Нил Форд и Марк Ричардс предлагают итеративный подход к выделению и оптимизации компонентов[6]. Такой подход акцентирует внимание на постепенном уточнении структуры системы и требований по мере накопления знаний.
Типичный цикл включает несколько стадий:[6]
- Формируется стратегия высокоуровневого разделения (например, техническое или доменное деление), определяется минимальная осмысленная развёртываемая единица — «кванта». Эти решения могут пересматриваться в процессе.
- На основании стратегии формируются начальные компоненты.
- К компонентам прикрепляются требования.
- Анализируются роли и ответственности каждого компонента для прояснения и минимизации пересечений.
- Оцениваются архитектурные характеристики (масштабируемость, устойчивость, сопровождаемость).
- При необходимости производится реорганизация компонентов на основе обратной связи от команд разработки.
Этот цикл может адаптироваться под специфику разных проектов и предметных областей.
Принципы проектирования
Принципы проектирования помогают инженеру ориентироваться в процессе разработки. Дэвис[7] предложил ряд принципов, уточнённых в последующих работах:
- Процесс проектирования не должен быть односторонним («туннельным зрением»)
- Хороший разработчик рассматривает альтернативы, оценивает их с учётом требований задачи и ресурсов.
- Проект должен быть прослеживаемым до модели анализа
- Поскольку один элемент проектной модели часто связан с несколькими требованиями, необходимы средства отслеживания соответствия проектных решений требованиям.
- Не стоит «изобретать велосипед»
- Для построения систем нужно использовать уже существующие шаблоны проектирования как альтернативу созданию новых решений с нуля.
- Проект должен минимизировать разрыв между программным продуктом и реальной задачей
- Структура программного решения должна по возможности отражать структуру предметной области.
- Проект должен быть единообразным и интегрированным
- Для этого определяются общие правила стиля до начала работы и особое внимание уделяется интерфейсам между компонентами.
- Проект должен быть гибким к изменениям
- Следующие разделы дополняют этот принцип концепциями, обеспечивающими масштабируемость и эволюционность проектных решений.
- Проект должен компенсировать нештатные ситуации
- Хорошо спроектированное ПО должно корректно реагировать на аномальные данные или сбои, в том числе завершать работу «мягко».
- Проектирование не тождественно кодированию
- Даже при создании детализированных проектных решений уровень абстракции проектной модели выше, чем исходный код.
- Качество проекта должно оцениваться на всех этапах
- Применяются различные концепции и метрики качества для поддержки процесса разработки.
- Проект должен проходить рецензирование с целью минимизации смысловых ошибок
- Важно обеспечить полноту, однозначность и непротиворечивость ещё до обсуждения технических деталей.
Концепции проектирования
Концепции проектирования образуют основу, на которой строятся более сложные методы. К этим концепциям относятся:
- Абстракция
- Сокращение объёма информации до главного — представление только релевантных признаков явления для поставленной задачи.
- Архитектура
- Общая структура программного комплекса, обеспечивающая его концептуальную целостность. Грамотно построенная архитектура способствует достижению параметров эффективности, качества, надёжности и экономичности.
- Иерархия управления
- Структура программы, отражающая порядок взаимодействия компонентов и передачу управления.
- Структура данных
- Способы логического представления и хранения данных.
- Шаблон проектирования
- Перенос накопленного опытного решения типовой задачи проектирования, что способствует ускорению разработки[8].
- Сокрытие информации
- Каждый модуль должен быть организован так, чтобы его внутренние данные были недоступны другим модулям без необходимости.
- Модульность
- Деление решения на части (модули).
- Уточнение
- Процесс пошаговой детализации — декомпозиция функций от общих формулировок к программным инструкциям.
- Программная процедура
- Фокусировка на обработке каждого модуля по отдельности.
- Структурное разбиение
- Горизонтальное и вертикальное деление программы на независимые части.
Грэди Буч выделяет абстракцию, инкапсуляцию, модульность и иерархию как основные принципы проектирования[9]. Комплекс этих принципов обозначается как PHAME (principles of hierarchy, abstraction, modularization, encapsulation)[10].
Аспекты проектирования
При проектировании программного обеспечения необходимо учитывать множество факторов, значимость которых определяется целями и требованиями конкретного проекта. Важнейшие аспекты:
- Совместимость
- Способность программы взаимодействовать с другими продуктами, например, обратная совместимость с более ранними версиями.
- Расширяемость (Extensibility)
- Возможность добавления новых функций без существенной перестройки архитектуры.
- Отказоустойчивость
- Способность ПО сопротивляться сбоям и восстанавливаться после них.
- Сопровождаемость
- Лёгкость внесения изменений и исправлений. Часто обеспечивается за счёт модульности и расширяемости.
- Модульность
- Строгое разделение ПО на независимые компоненты, что упрощает тестирование и дальнейшее развитие.
- Издержки
- Ресурсы, расходуемые на поддержание программных и аппаратных требований.
- Производительность
- Выполнение задач за приемлемое время и ограниченное потребление памяти.
- Портируемость
- Применимость программного продукта в разных условиях и на различных платформах.
- Надёжность
- Способность выполнять требуемые функции в заявленных условиях и сроках.
- Повторное использование
- Возможность применения частей существующего ПО в новых проектах с минимальными изменениями.
- Устойчивость
- Работа в условиях стресса или некорректных данных, например, при нехватке памяти.
- Масштабируемость
- Адаптация к увеличению нагрузки, числу пользователей или функций. Как отмечает Марк Брукер, «система масштабируема в диапазоне, где предельная стоимость обработки дополнительной нагрузки почти постоянна». Бесcерверные технологии удовлетворяют этому критерию, однако важно учитывать суммарную стоимость владения[11].
- Безопасность
- Устойчивость к внешним воздействиям и атакам.
- Удобство работы
- Интерфейс должен быть интуитивным для пользователя. Значения параметров по умолчанию должны быть хорошо подобраны для большинства пользователей[12].
Языки моделирования
Язык моделирования позволяет формализованно описывать информацию, знания или системы по единому набору правил — графически или текстово. Основные языки моделирования для проектирования программного обеспечения:
- Язык описания архитектуры (ADL)
- Формализует архитектуру программной системы.
- Business Process Modeling Notation (BPMN)
- Язык моделирования бизнес-процессов.
- EXPRESS и EXPRESS-G (ISO 10303-11)
- Международный стандарт языков моделирования данных общего назначения.
- Extended Enterprise Modeling Language (EEML)
- Применяется для моделирования бизнес-процессов на разных уровнях.
- Блок-схема
- Схематичное изображение алгоритмов и процессов.
- Fundamental Modeling Concepts (FMC)
- Язык моделирования для комплексных программных систем.
- IDEF
- Семейство языков моделирования, включающее IDEF0 для функционального моделирования, IDEF1X для моделирования информации и IDEF5 для онтологий.
- Jackson Structured Programming (JSP)
- Метод структурного программирования, отражающий соответствие между структурой данных и логикой программы.
- LePUS3
- Объектно-ориентированный визуальный язык описания архитектуры и формальных спецификаций, в частности для больших проектов на Java, C++ и C# и моделирования шаблонов проектирования.
- Унифицированный язык моделирования (UML)
- Универсальный язык для описания программных систем структурно и поведением; поддерживает графическую нотацию и расширение профилями.
- Alloy
- Язык для формализации сложных структурных ограничений и поведения в ПО, основанный на реляционной логике первого порядка.
- Systems Modeling Language (SysML)
- Общий язык моделирования для инженерии систем.
- Фреймворк сервис-ориентированного моделирования (SOMF)[13]
Примечания
- ↑ Ralph, P.; Wand, Y. A proposal for a formal definition of the design concept. // Design Requirements Workshop (LNBIP 14) / под ред. K. Lyytinen, P. Loucopoulos, J. Mylopoulos, W. Robinson. Springer-Verlag, 2009. С. 103—136. DOI:10.1007/978-3-540-92966-6_6.
- ↑ Freeman, Peter; David Hart (2004). “A Science of design for software-intensive systems”. Communications of the ACM. 47 (8): 19—21. DOI:10.1145/1012037.1012054. Дата обращения 2024-06-10.
|access-date=требует|url=(справка) - ↑ Ralph, P.; Wand, Y. A proposal for a formal definition of the design concept. // Design Requirements Engineering: A Ten-Year Perspective / под ред. K. Lyytinen, P. Loucopoulos, J. Mylopoulos, W. Robinson. Springer-Verlag, 2009. С. 103—136.
- ↑ Dijkstra, E. W. On the cruelty of really teaching computing science (англ.) (1988). Дата обращения: 10 января 2014.
- ↑ Knuth, Donald E. Notes on the Errors of TeX (англ.) (1989). Дата обращения: 10 июня 2024.
- ↑ 1 2 Fundamentals of Software Architecture: An Engineering Approach. — O'Reilly Media, 2020. — ISBN 978-1492043454.
- ↑ Davis, A. «201 Principles of Software Development». McGraw Hill, 1995.
- ↑ Judith Bishop. C# 3.0 Design Patterns: Use the Power of C# 3.0 to Solve Real-World Problems (англ.). C# Books from O'Reilly Media. Дата обращения: 15 мая 2012.
- ↑ Booch, Grady. Object-Oriented Analysis and Design with Applications : [англ.]. — 3rd. — Addison Wesley, 2004. — ISBN 0-201-89551-X.
- ↑ Suryanarayana, Girish. Refactoring for Software Design Smells : [англ.]. — Morgan Kaufmann, 2014-11. — P. 258. — ISBN 978-0128013977.
- ↑ Building Serverless Applications on Knative : [англ.]. — O'Reilly Media. — ISBN 9781098142049.
- ↑ Scenario-Based Design: Envisioning Work and Technology in System Development : [англ.]. — New York : John Wiley & Sons, 1995. — ISBN 0471076597.
- ↑ Bell, Michael. Introduction to Service-Oriented Modeling // Service-Oriented Modeling: Service Analysis, Design, and Architecture : [англ.]. — Wiley & Sons, 2008. — ISBN 978-0-470-14111-3.
Литература
- Pressman R. S. Software engineering: a practitioner’s approach. McGraw-Hill, 2001. ISBN 0-07-365578-3.
- Davis, A. 201 Principles of Software Development. McGraw Hill, 1995.