Предметная модель защищает допустимые состояния
Пусть заказ может быть черновиком или подтверждённым, а подтверждение пустого заказа запрещено. Это правило относится к смыслу заказа, а не к конкретной кнопке на экране. Если проверять его только в контроллере, другой способ вызова может её пропустить. В предметной модели стоит явно выразить допустимый переход и условия его выполнения. Имена Order и Confirm имеют смысл, когда команда одинаково понимает соответствующие понятия. При этом одинаковое слово в разных частях бизнеса может обозначать разные модели: заказ для доставки и для расчётов содержит разные существенные сведения. Такое различие полезно обозначать границами контекстов.
Сценарий организует работу, инфраструктура выполняет детали
Сценарий подтверждения получает входные данные, находит нужный заказ, вызывает предметное действие и организует сохранение результата. Само правило о непустом заказе не должно зависеть от формата HTTP-запроса или конкретного сервера базы данных. Для обращения к внешним возможностям ядро может определять интерфейсы, а инфраструктура — реализовывать их. Например, договорённость о сохранении заказа отделяется от конкретного механизма хранения. Это не означает, что каждому классу необходим собственный интерфейс. Граница полезна там, где она выражает значимую зависимость и позволяет обсуждать правило независимо от технической реализации.
Правильный слой не отменяет других ограничений
Допустим, два запроса одновременно пытаются изменить один заказ. Наличие проверки в объекте ещё не решает вопрос согласованности сохранения. Транзакции, контроль конкурентных изменений и ограничения хранения требуют отдельного проектирования. Также следует различать удобство проверки входа в интерфейсе и защиту предметного правила: они решают связанные, но разные задачи. Для простой операции с данными сложная модель может оказаться избыточной. Архитектурный выбор стоит объяснять характером правил и изменений, а не числом созданных слоёв. Хороший признак — возможность показать конкретный сценарий и назвать ответственность каждого участвующего элемента.
Попробуйте на практике
Разложите сценарий подтверждения вымышленного заказа по карточкам. Писать код и устанавливать среду разработки для задания не требуется.
- Запишите правило: пустой заказ нельзя подтвердить. Добавьте два состояния и разрешённый переход, не связывая их с экраном или базой данных.
- Создайте три карточки: предметная модель, сценарий приложения и инфраструктура. Распределите действия: проверить переход, загрузить заказ, организовать сохранение и выполнить запись выбранным способом.
- Нарисуйте зависимости так, чтобы предметное правило не требовало знания о контроллере и конкретном механизме хранения. Отдельно обозначьте нужный интерфейс взаимодействия.
- Придумайте два пути вызова: веб-запрос и фоновое задание. Проверьте, остаётся ли запрет пустого заказа общим для обоих.
- Добавьте вопрос о двух одновременных изменениях. Укажите, почему одна предметная проверка не даёт полного ответа о согласованности данных.
Как проверить результат. Схема готова, если правило можно объяснить без названий внешних библиотек, сценарий имеет понятную последовательность, а техническое хранение отделено от смысла перехода. Неопределённые вопросы конкурентности должны быть отмечены явно.
Частые вопросы
DDD обязательно требует микросервисов?
Нет. Границы предметных понятий можно выделять и внутри одного приложения. Разделение развёртывания является отдельным решением с собственными затратами и ограничениями.
Достаточно ли перенести классы в папку Domain?
Нет. Важно содержание модели и направление зависимостей. Если существенные правила по-прежнему разбросаны по контроллерам, название папки не делает их согласованными и не защищает от обхода через другой сценарий.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.