Несмотря на довольно большое количество различных подходов к построению (дизайну) приложений можно выделить два основных:
- Transaction Script;
- Domain Model.
Первый из них достаточно прост и при этом позволяет довольно удобно организовать ваш код в виде отдельных процедур обрабатывающих внешние запросы, но при усложнении логики приложения, ее размазывание между большим количеством процедур приводит к дублированию кода и другим нежелательным последствиям. И к тому же если работа с БД происходит в том-же месте где и обработка логики, становится затруднительным использование модульных тестов, что в свою очередь не добавляет надежности вашему коду.
С другой стороны, использование доменной модели в начале написания приложения выглядит чрезмерным усложнением, так как добавляет довольно много дополнительного кода, да и само по себе не защищает от ошибок и проблем. Но в перспективе такой подход позволяет развивать логику программы не приводя к экспоненциальному росту сложности.
Что же выбрать
Что выбрать в начале работы над приложением, особенно в ситуации когда вообще не понятно будет ли им кто-то пользоваться и каков будет его масштаб через 3 года разработки? Сложный момент, но можно попытаться совместить приятное с полезным и не идти на компромисс.
Итак, давайте поищем схожие моменты в двух подходах. Ну и конечно обратим внимание на отличия.
Различия и общность
Слой приложения (Application Layer)
Начнем с того, что слой приложения, в котором располагаются сервисы приложения с наборами функций реализующих варианты использования, вполне напоминает подход Transaction Script. Основное отличие в том, что в функциях сервисов нет логики предметной области, в отличие от процедур скрипта. Но это не большая проблема и на начальном этапе размещение там примитивной логики предметной области хоть и будет нарушением концепции DDD, но не приведет к существенным проблемам.
Инфраструктура
Другой вопрос — наличии в скрипте логики работы с БД и другими инфраструктурными системами. Вот этого лучше избежать изначально, так как это усложняет тестирование, смешивает ответственности, да и просто плохо выглядит. Но и в этом случае даже для Transaction Script хорошей практикой будет изолировать работу с инфраструктурой в отдельном слое приложения.
Слой логики предметной области (Domain Layer)
Как я уже упомянул, на старте всю логику предметной области можно оставить в слое приложения, ну а потом, когда она начнет усложняться, можно вынести ее в отдельный слой и завернуть в сущности предметной области.
Подводя итоги
Итак, безкомпромиссное решение возможно. Да, надо в любом случае будет отделить инфраструктуру от остальной логики и немного заморочиться с инверсией зависимостей, чтобы логика приложения не зависела от инфраструктуры, а получалось наоборот. Однако это все небольшая цена за возможность в последствии легко превратить Transaction Script в DDD, получив быстрый старт работы над приложением и линейный рост его сложности в последующем.