- •Введение
- •1. Цели и задачи архитектора информационных систем
- •1.1. Цели создания информационных систем
- •1.2. Базовые структуры информационных систем
- •1.3. Уровни реализации архитектуры ИС
- •1.4. Атрибуты качества информационных систем
- •1.5. Сопровождение бизнес-ориентированных ИС
- •2.2. Структурное программирование
- •2. Парадигмы программирования
- •2.1. Модульное программирование
- •2.4. Функциональное программирование
- •2.5. Общие тенденции развития парадигм программирования
- •3. Чистая архитектура
- •3.1. Кричащая архитектура
- •3.2. Принципы SOLID
- •3.2.1. Принцип единственной ответственности
- •3.2.2. Принцип открытости/закрытости
- •3.2.3. Принцип подстановки Б. Лисков
- •3.2.4. Принцип разделения интерфейсов
- •3.2.5. Принцип инверсии зависимостей
- •3.3. Программные компоненты и принципы их организации
- •3.3.1. Диаграмма компонентов
- •3.3.2. Принципы взаимосвязи компонентов
- •3.3.3. Принцип эквивалентности повторного использования и выпусков
- •3.3.4. Принцип согласованного изменения
- •3.3.5. Принцип совместного повторного использования
- •3.3.6. Сравнение принципов взаимосвязи компонентов
- •3.4. Компонентный подход как способ динамического изменения архитектуры ИС
- •3.4.1. Принцип ацикличности зависимостей
- •3.4.2. Принцип устойчивых зависимостей
- •3.4.3. Принцип устойчивости абстракций
- •3.4.4. Графическая интерпретация принципов SDP и SAP
- •3.5. Вычислительные архитектуры ИС
- •3.5.1. Клиент-серверная архитектура
- •3.5.2. Трёхзвенная архитектура
- •3.5.3. Микросервисная архитектура
- •3.6. Шаблоны и антишаблоны проектирования ИС
- •3.6.1. Шаблоны проектирования
- •3.6.2. Антишаблоны проектирования
Пример 2 при этом может выглядеть более предпочтительным:
представленный в нем высокий уровень абстракции позволяет в тео-
рии решать широкий спектр задач, а не только фокусироваться на зада-
чах, присущих интернет-магазину, однако поиск проблем такая абст-
ракция серьёзно усложнит, так как запросы от пользователей системы поступают на обычном, а не на высоко-абстрактном языке [23, 25].
Таким образом, высокая абстракция иногда позволяет сократить лишь время первоначальной реализации того или иного функционала (в
примере выше абстракция может окупить себя лишь в случае появле-
ния задачи по автоматизации сходной предметной области), но значи-
тельно усложняет сопровождение системы. В связи с этим архитекто-
рам ИС всегда целесообразно взвешивать ценность такой экономии ре-
сурсов разработчика.
3.2. Принципы SOLID
Принципы SOLID, введённые Р.Мартином в его книге «Чистая ар-
хитектура» [25], расширяют понятие чистой архитектуры следующими пятью принципами (которые легли в основу аббревиатуры):
–Single Responsibility Principle («Принцип единственной ответ-
ственности», SRP);
–Open-Closed Principle («Принцип открытости-закрытости», OCP);
–Liskov Substitution Principle («Принцип подстановки Лисков», LSP);
–Interface Segregation Principle («Принцип разделения интерфей-
са», ISP);
–Dependency Inversion Principle («Принцип инверсии зависимо-
стей», DIP).
28
3.2.1. Принцип единственной ответственности
Из всех принципов SOLID наиболее трудно понимаемым и широко распространенным является принцип единственной ответственности.
Принцип единственной ответственности предполагает, что у каждой программной сущности должна быть одна и только одна причина для изменения.
Суть принцип заключается в том, что для каждого класса про-
граммы должно быть определено единственное назначение, а все ре-
сурсы, необходимые для его осуществления, инкапсулированы в класс.
Механизм инкапсуляции позволяет разграничить доступ пользователя к различным составляющим компонента (данным методам), для того чтобы минимизировать влияние второстепенных факторов на основное содержание.
Нередко бывают случаи, когда класс выполняет много различных функций, которые можно разместить по нескольким классам. Пусть существует некоторый класс «Управление заказами», имеющий пове-
дение «Создать заказ» и «Оплатить заказ». Указанный класс будет яв-
ляться нарушением принципа единственной ответственности, так как он выполняет две задачи: создание заказа и его оплату. Такой класс це-
лесообразно разделить на «Управление заказами» (для создания зака-
зов) и «Проведение платежей» (для оплаты). При этом принцип не за-
прещает создавать новый функционал в классах. Так, например, «Управление заказами» можно расширить методом «Добавить товар»,
так как функционал добавления товара также относится к процессу создания заказа.
Проверку корректности реализации принципа можно провести,
анализируя диаграмму вариантов использования (UseCase diagram) [31].
На диаграмме следует определить, к какому функциональному требо29
ванию относится рассматриваемая программная сущность. Затем необ-
ходимо найти соответствующего функциональному требованию инте-
рактора (англ. actor – человек или внешняя система, использующая рассматриваемую ИС). В случае если владельцами программной сущ-
ности окажутся два или более интеракторов, то это будет считаться на-
рушением принципа единственной ответственности: у каждого из инте-
ракторов могут быть свои причины запросить изменение рассматри-
ваемой программной сущности, что впоследствии может привести к конфликтной модификации программного кода: когда было внесено изменение для одного интерактора, которое мешает работе другого ин-
терактора.
Пример диаграммы последовательностей, не нарушающей прин-
цип SOLID, приведён на рис. 2.
Рисунок 2 – Диаграмма вариантов использования системы управления рестораном
На рисунке изображено четыре интерактора: менеджер, официант,
клиент, шеф-повар, каждый из которых решает свои задачи:
–официант открывает счёт на обслуживание, обслуживает кли-
ентов, формирует заказ, передаёт заказ на кухню;
30
–клиент заказывает блюда, просматривает меню, оплачивает счет, оставляет отзывы;
–шеф-повар принимает заказ на кухне, готовит блюда, формиру-
ет список продуктов для закупки;
–менеджер формирует рейтинг блюд, осуществляет подсчёт прибыли, устанавливает цены на блюда, занимается поставкой продукции.
3.2.2. Принцип открытости/закрытости
Принцип открытости/закрытости был сформулирован Бертраном Мейером в 1988 году [25]. Данный принцип формулируется следую-
щим образом. Программные сущности должны быть открыты для рас-
ширения и закрыты для изменения. Данный принцип признается как руководство по проектированию классов и модулей. На уровне архи-
тектурных компонентов этот принцип приобретает ещё большую цен-
ность.
В случае объектно-ориентированного программирования принцип открытости/закрытости требует, чтобы единожды реализованный класс впредь больше не изменялся. При этом внесение изменений в класс рас-
сматривается как чрезвычайная ситуация. Вторая часть принципа гово-
рит о том, что при необходимости внесения изменений в ИС следует добавлять новые программные сущности, являющиеся наследниками тех классов, которые требуется изменить. Ограничений на создание та-
ких сущностей принцип открытости/закрытости не накладывает. Одна-
ко предпочтительным считается использование архитектурных шабло-
нов проектирования (описание шаблонов приведено в разделе 3.6).
Проблема, которую призван решить данный принцип: непредна-
меренное изменение уже использующегося конечными пользовате-
31
