Трехслойный паттерн корпоративной архитектуры

preview

У крупного бизнеса существуют разные потребности, поэтому в зависимости от условий, которые выдвигает бизнес к проектируемой системе, следует подбирать наиболее оптимальную архитектуру.

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

Наиболее удачным решением для быстрого прототипирования и развертывания системы является трехслойный монолит. На сегодняшний день практически всегда отдается предпочтение в пользу веб-технологий и уровень представления выполняется в виде тонкого клиента, а базовая часть в виде бэкенда, состоящего из двух слоев - данных и бизнес-логики.

Слоистая архитектура

Бизнес-логика

Duration: 10

В предыдущей лекции мы рассмотрели общие варианты реализации слоя представления и слоя данных, в этой лекции я хочу остановиться подробно уровне с бизнес-логикой. В книге "Шаблоны корпоративных приложений" Мартина Фаулера описаны четыре основных паттерна, которые применяются в бизнес-решениях при использовании слоистой архитектуры:

- "Transaction script"
- "Domain model"
- "Table Module"
- "Service Layer"

При реализации данных шаблонов следует придерживаться принципа разделения низкоуровнего доступа к хранилищам данных (БД) и непосредственно самими данными. Изоляция может быть реализована с помощью служебных сервисов, отвечающих за реализацию хранения данных и работы с интерфейсами СУБД.

Я хочу предложить типовую архитектуру монолитного, модульного веб-приложения, соответствующего шаблонам, перечисленным у Фаулера.

С учетом развития SPA и переноса значительной функциональности с сервера на фронт, архитектура фронтенда и бэкенда становятся абсолютно идентичными, за тем исключением, что со стороны бэкенда API выполняет пассивную роль (отвечает на запросы), а на стороне фронтенда активную роль (делает запросы).

Модульное представление

Логика приложения: - API - Сервисный уровень - Инфраструктурный уровень

Логика домена: - Бизнес-логика

Transaction script

Duration: 10

> Идея: Способ организации бизнес-логики по процедурам, каждая из которых > обслуживает один запрос, инициируемый слоем представления. > Шаблоны корпоративных приложений. М. Фаулер

Это шаблон является базовым решением в системах, где бизнес-задача может быть представлена одной транзакцией в СУБД. Обычно в таких системах нагрузка на слой бизнес логики минимальна и сводится к проверке входных данных, координации представлений и выработке единого интерфейса.

Жизненный цикл Transaction script

Частые ошибки: - объединение сценария транзакции и источника данных; - толстый контроллер; - сложная логика, не подходящая к реализации в рамках простой транзакции;

Где может быть реализован "transaction script": - сервис - модель

Варианты реализации: - все сценарии в одном классе; - паттерн "команда".

Недостатки: - большое дублирование кода; - нельзя покрыть сложную логику.

Domain model

Duration: 10

Этот шаблон позволяет построить сложную бизнес-логику, используя классы для представления связей и отношений между сущностями предметной области.

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

Существует два варианта реализации: - простая - когда одна таблица БД отображается в один класс бизнес-логики - сложная - когда существует сложная иерархия наследования и множество отношений между сущностями;

Допускается комбинация доменной модели и скриптов транзакции. Использование одного паттерна не исключает использование других паттернов.

Частые ошибки: - неверная грануляция - слишком мелкие или слишком крупные классы; - перемешивание бизнес-логики и технических аспектов; - смешивание источников данных и доменных моделей; - представление моделей предметной области в виде сервисов.

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

Варианты реализации: - модели (часто) - сервисы (крайне редко, так как обычно это неудачное решение)

Table module

Duration: 10

> Идея: Объект, охватывающий логику обработки всех записей хранимой > или виртуальной таблицы базы данных. > Шаблоны корпоративных приложений. М. Фаулер

Этот шаблон упрощает процесс проектирования за счет введения простого правила "одна таблица - один класс". Такое упрощение сделано из-за постоянных проблем с поиском правильного места для запросов к БД и отображении результатов этих запросов в доменной модели. Шаблон модуль таблицы изначально проектируется как способ установить связь между БД и сущностями приложения.

Модуль таблицы содержит множество данных и операций над ними. При этом множество данных может быть использована в нескольких класса, реализующих "Table Module", а могут быть жестко связаны с источником данных.

Модуль таблицы может манипулировать данными в том числе через статические методы.

Преимущества: - изоляция логики обработки данных - повторное использование в разрезе разных наборов данных - упрощение разделения ответственности

Недостатки: - не подходит для реализации сложной логики

Варианты реализации: - Сервис

Жизненный цикл Table module

Service layer

Duration: 10

> Идея: Схема определения границ приложения посредством слоя служб, > который устанавливает множество доступных действий и координирует > отклик приложения на каждое действие > Шаблоны корпоративных приложений. М. Фаулер

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

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

  • интерфейсы доступа к домену - набор тонких интерфейсов, поверх логики домена
  • сценарий операций - более "толстый" слой реализующих логику приложения, но за бизнес-логикой обращаются к слою домена.

Я считаю, что такой подход устарел и на сегодняшний день, мне нравится подход с использованием IoC-контейнера и внедрением зависимостей (DI). В рамках этого решения выделяется слой сервисов, которые могут быть использованы в контроллерах или скриптах транзакций.

Доменная модель не должна ничего знать о сервисах, но сервисы могут знать о доменной модели.

Жизненный цикл Service layer и Transaction script

Жизненный цикл Service layer и Domain logic