Перейти к содержимому

Программная архитектура и слои

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

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

Типовые слои:

  • presentation layer: взаимодействие с пользователем или внешним клиентом;
  • application layer: сценарии приложения и координация пользовательских целей;
  • domain/model layer: предметная модель и бизнес-правила;
  • infrastructure/data access layer: хранение, файлы, внешние сервисы, сетевые интеграции.

Главное правило слоистой модели — контролировать зависимости. Пользовательский интерфейс или контроллер может обращаться к application layer. Application layer координирует сценарий и использует предметную модель. Infrastructure layer реализует технические детали хранения и интеграции. Предметная модель не должна напрямую зависеть от базы данных, HTTP-клиента, файловой системы или UI.

Типовые роли классов:

Роль Ответственность
Controller принять внешнее действие и передать его дальше
ApplicationService скоординировать сценарий приложения
DomainService выполнить предметную операцию, если она не принадлежит одному объекту
Repository скрыть способ загрузки и сохранения объектов
DTO перенести данные через границу слоя или интерфейса
Mapper преобразовать одну техническую форму данных в другую
Gateway / Adapter изолировать внешнюю систему
Entity / Model представить предметный объект в технической модели

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

Слоистая архитектура полезна только тогда, когда у слоёв есть разные причины для изменения. Интерфейс может меняться из-за требований пользователей. Application layer меняется из-за сценариев. Domain/model layer меняется из-за предметных правил. Infrastructure layer меняется из-за базы данных, внешних сервисов и технологий.

Слои не равны папкам. Папки помогают организовать код, но архитектурный смысл появляется только тогда, когда зависимости между классами соответствуют выбранным ролям. Если контроллер сам проверяет бизнес-правила, формирует SQL и вызывает внешний сервис, слоистая архитектура фактически отсутствует.

Допустимость зависимости можно проверять простым вопросом: станет ли предметная логика зависеть от технической детали? Если правило отмены заказа зависит от HTTP-клиента или SQL-запроса, зависимость выбрана плохо. Если сервис приложения зависит от интерфейса репозитория или шлюза, это нормальный способ скрыть инфраструктуру за абстракцией.

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

Для UML-фиксации слоёв используются диаграммы пакетов, а логические модули и их контракты раскрываются через диаграммы компонентов. Если нужно показать внутренние части одного сложного компонента, используется диаграмма внутренней структуры.

Когда нужно объяснить крупные границы выполнения системы, слои и их решения можно собрать в представлении контейнеров C4; внутренности сложного приложения уточняются в представлении компонентов.