- •Введение
- •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. Антишаблоны проектирования
С учётом вышеизложенного диаграмму противоречий и основную задачу архитектора при взаимодействии с ней можно изобразить так,
как показано на рис. 7.
Рисунок 7 – Взаимосвязь принципов REP, CCP, CRP
3.4. Компонентный подход как способ динамического изменения архитектуры ИС
Фокус архитектора на взаимосвязи компонентов порождает такую парадигму проектирования, как компонентно-ориентированное проек-
тирование [35].
Компонентно-ориентированное программирование (англ. component-oriented programming, COP) – парадигма программирования,
существенным образом опирающаяся на понятие компонента, предна-
значенного для повторного использования и развёртывания и реали-
зующегося в виде множества языковых конструкций (например, «клас-
сов» в объектно-ориентированных языках программирования), объеди-
нённых по общему признаку и организованных в соответствии с опре-
делёнными правилами и ограничениями.
43
Компонентный подход задаёт очень лаконичную и читаемую структуру кода. Это облегчает дальнейшую поддержку разработанного приложения. Если ваша разработка – это небольшой одностраничный сайт, то плюсы от компонентного подхода не будут так заметны.
Компонентно-ориентированный подход использует понятие сре-
зов: различных точек зрения, на основе которых можно описывать ИС.
Выделяют вертикальные срезы и горизонтальные уровни ИС [25].
Вертикальные архитектурные срезы описывают функционал сис-
темы на разных уровнях реализации: каким образом та или иная функ-
ция отражается в интерфейсе системы, как обрабатывается внутри сис-
темы и каким образом организовано хранение данных в контексте рас-
сматриваемой функции.
Горизонтальные срезы (уровни) описывают всю совокупность функций, реализованных на одном уровне системы. Уровень интер-
фейса будет включать в себя все функциональные возможности интер-
фейса. Уровень модели описывает основную логику приложения, уро-
вень данных – способы хранения данных на физических носителях.
Понятие чистой архитектуры предлагает выделять следующие го-
ризонтальные уровни, представленные на рис. 8:
–уровень программных сущностей (Entities) – используется для представления статичной модели предметной области, описы-
вается диаграммами классов или сущностей [36, 37, 38];
–уровень бизнес-логики (Use Cases) – используется для описа-
ния (моделирования) бизнесили производственных процессов,
описывается диаграммами потоков данных или диаграммами моделирования бизнес-процессов [38, 39, 40, 41];
44
–уровень адаптеров (Controllers/Gateways/Presenters) – использу-
ется для изоляции бизнес-логики от её деталей реализации по-
средством конкретных технологий;
–уровень представления (User Interface, Database, Web API, Devices) – располагает внутри себя непосредственные реализа-
ции (проекции) модели предметной области на конкретные тех-
нологии.
Рисунок 8 – Архитектурные слои в контексте чистой архитектуры Понятие чистой архитектуры предполагает, что все зависимости
должны быть направлены «снизу вверх», то есть от конкретных реали-
заций к абстрактным моделям предметной области. При этом проекти-
рование системы должно выполняться в противоположную сторону: от более абстрактных концепций до наиболее конкретных реализаций.
Для обеспечения подобной архитектуры Р.Мартин выделяет сле-
дующие принципы сочетаемости компонентов [25]:
–принцип ацикличности зависимостей (Acyclic Dependencies Principle, ADP);
–принцип устойчивых зависимостей (Stable Dependencies Principle, SDP);
45
–принцип устойчивости абстракций (Stable Abstractions Principle, SAP).
3.4.1. Принцип ацикличности зависимостей
Принцип ацикличности зависимостей предлагает рассматривать диаграмму компонентов, описывающую ИС с помощью ориентирован-
ного графа, в котором узлами являются сами компоненты, а направле-
ния зависимостей – рёбрами направленного графа. Принцип утвержда-
ет, что при проектировании ИС следует избегать циклов в таком графе.
Для борьбы с циклическими зависимостями предлагается все зави-
симости между компонентами организовывать на основе интерфейсов
(как элементов с наибольшей возможной степенью абстракции). Изме-
нение направления зависимости в таком случае можно проводить пу-
тём переноса логики создания экземпляра компонента из независимого компонента в зависимый. Процесс переноса наглядно изображён на рис. 9.
Рисунок 9 – Алгоритм изменения направления зависимостей компонентов
В исходном состоянии компонент Package A зависит от компонен-
та Package B. Для инверсии зависимости достаточно в компоненте
Package A создать интерфейс, который будет использоваться классом
Object A компонента Package A и который будет реализовываться клас-
46
