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

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

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

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

Для учебной модели удобно использовать простую слоистую структуру. Она не требует углубления в DDD, Clean Architecture или конкретный backend-фреймворк, но помогает не смешивать ответственности.

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

  • 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-запроса, зависимость выбрана плохо. Если сервис приложения зависит от интерфейса репозитория или шлюза, это нормальный способ скрыть инфраструктуру за абстракцией.

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