В КУРСЕ?

Разбираемся в теме

DDD и Clean Architecture в C#: где должно жить правило заказа

Папки с названиями слоёв ещё не делают приложение понятным. Полезнее проверить, где находится правило и от каких деталей оно зависит. DDD помогает описывать предметную область её собственными понятиями, а Clean Architecture направляет зависимости так, чтобы существенные правила не растворялись в интерфейсе и хранении данных. Рассмотрим условный заказ на языке C#, без обязательного набора библиотек и готового шаблона проекта.

Предметная модель защищает допустимые состояния

Пусть заказ может быть черновиком или подтверждённым, а подтверждение пустого заказа запрещено. Это правило относится к смыслу заказа, а не к конкретной кнопке на экране. Если проверять его только в контроллере, другой способ вызова может её пропустить. В предметной модели стоит явно выразить допустимый переход и условия его выполнения. Имена Order и Confirm имеют смысл, когда команда одинаково понимает соответствующие понятия. При этом одинаковое слово в разных частях бизнеса может обозначать разные модели: заказ для доставки и для расчётов содержит разные существенные сведения. Такое различие полезно обозначать границами контекстов.

Сценарий организует работу, инфраструктура выполняет детали

Сценарий подтверждения получает входные данные, находит нужный заказ, вызывает предметное действие и организует сохранение результата. Само правило о непустом заказе не должно зависеть от формата HTTP-запроса или конкретного сервера базы данных. Для обращения к внешним возможностям ядро может определять интерфейсы, а инфраструктура — реализовывать их. Например, договорённость о сохранении заказа отделяется от конкретного механизма хранения. Это не означает, что каждому классу необходим собственный интерфейс. Граница полезна там, где она выражает значимую зависимость и позволяет обсуждать правило независимо от технической реализации.

Правильный слой не отменяет других ограничений

Допустим, два запроса одновременно пытаются изменить один заказ. Наличие проверки в объекте ещё не решает вопрос согласованности сохранения. Транзакции, контроль конкурентных изменений и ограничения хранения требуют отдельного проектирования. Также следует различать удобство проверки входа в интерфейсе и защиту предметного правила: они решают связанные, но разные задачи. Для простой операции с данными сложная модель может оказаться избыточной. Архитектурный выбор стоит объяснять характером правил и изменений, а не числом созданных слоёв. Хороший признак — возможность показать конкретный сценарий и назвать ответственность каждого участвующего элемента.

Попробуйте на практике

Разложите сценарий подтверждения вымышленного заказа по карточкам. Писать код и устанавливать среду разработки для задания не требуется.

  1. Запишите правило: пустой заказ нельзя подтвердить. Добавьте два состояния и разрешённый переход, не связывая их с экраном или базой данных.
  2. Создайте три карточки: предметная модель, сценарий приложения и инфраструктура. Распределите действия: проверить переход, загрузить заказ, организовать сохранение и выполнить запись выбранным способом.
  3. Нарисуйте зависимости так, чтобы предметное правило не требовало знания о контроллере и конкретном механизме хранения. Отдельно обозначьте нужный интерфейс взаимодействия.
  4. Придумайте два пути вызова: веб-запрос и фоновое задание. Проверьте, остаётся ли запрет пустого заказа общим для обоих.
  5. Добавьте вопрос о двух одновременных изменениях. Укажите, почему одна предметная проверка не даёт полного ответа о согласованности данных.

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

Частые вопросы

DDD обязательно требует микросервисов?

Нет. Границы предметных понятий можно выделять и внутри одного приложения. Разделение развёртывания является отдельным решением с собственными затратами и ограничениями.

Достаточно ли перенести классы в папку Domain?

Нет. Важно содержание модели и направление зависимостей. Если существенные правила по-прежнему разбросаны по контроллерам, название папки не делает их согласованными и не защищает от обхода через другой сценарий.

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

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов