Материал из РУВИКИ — свободной энциклопедии

Проектирование программного обеспечения

Проектирование программного обеспечения (англ. 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]

Примечания

[править | править код]
  1. 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.
  2. 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= (справка)
  3. 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.
  4. Dijkstra, E. W. On the cruelty of really teaching computing science (англ.) (1988). Дата обращения: 10 января 2014.
  5. Knuth, Donald E. Notes on the Errors of TeX (англ.) (1989). Дата обращения: 10 июня 2024.
  6. 1 2 Fundamentals of Software Architecture: An Engineering Approach. — O'Reilly Media, 2020. — ISBN 978-1492043454.
  7. Davis, A. «201 Principles of Software Development». McGraw Hill, 1995.
  8. 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.
  9. Booch, Grady. Object-Oriented Analysis and Design with Applications : [англ.]. — 3rd. — Addison Wesley, 2004. — ISBN 0-201-89551-X.
  10. Suryanarayana, Girish. Refactoring for Software Design Smells : [англ.]. — Morgan Kaufmann, 2014-11. — P. 258. — ISBN 978-0128013977.
  11. Building Serverless Applications on Knative : [англ.]. — O'Reilly Media. — ISBN 9781098142049.
  12. Scenario-Based Design: Envisioning Work and Technology in System Development : [англ.]. — New York : John Wiley & Sons, 1995. — ISBN 0471076597.
  13. 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.