Простите за незнание, я новичок в DDD, так что будьте осторожны.
Я работаю над большой системой управления данными на основе конфигурации. Система построена путем указания частей конфигурации (таких как бизнес-правила, процессы и проверки) во внешнем синтаксисе. Скажем так, синтаксис представляет собой конгломерат DSL на основе Groovy и Drools.
Мне нравятся идеи простоты, которые предлагает DDD, в частности, отделяя проблемы инфраструктуры от основных концепций предметной области.
Однако мне сложно применить некоторые концепции DDD из-за настраиваемого характера системы. И поведение (процессы), и проверка, и бизнес-правила определяются внешними по отношению к системе. Таким образом, сущности в домене по сути не имеют собственного поведения. Скорее они деликатны по отношению к «валидатору», «механизму правил» или «механизму рабочего процесса».
Поясню на примере. Допустим, моя система управляет сотрудниками компании. Не задумываясь, вы можете представить, что в моем домене есть объект "Сотрудник" и "Компания".
Следуя DDD, я пытаюсь смоделировать сценарий повышения по службе. Вы можете увидеть новый метод для Employee, который называется Promote (Employee.promote). У нас могло бы быть бизнес-правило, указывающее, что сотрудника нельзя повышать дважды в течение одного года (да, это все выдумано). Поэтому у меня могло быть что-то вроде:
public void promote( EmployeeLevel newLevel ) {
if ( hasBeenPromotedThisYear( this ) {
throw new InvalidPromotionException
Что ж, в приложении, с которым я работаю, это бизнес-правило будет перенесено в механизм правил. После DDD я мог сделать что-то вроде:
if( promotionRules.isEligibleForPromotion(this)
Чтобы воплотить мои правила. Однако эта система гораздо более универсальна. Сама операция «продвижения» определяется как «Процесс» посредством внешней конфигурации. Итак, во время компиляции я даже не знал бы, есть ли у меня операция «повышения» для этого сотрудника. Таким образом, объект моего сотрудника становится довольно простым с точки зрения кода, делегируя все функции конфигурации. Это может выглядеть примерно так:
public class Employee {
public void execute( Process process )
Или альтернативно
public class EmployeeProcess {
public void process( Employee employee )
У меня вопрос: имеет ли смысл DDD в этом приложении? Должен ли я вместо этого просто моделировать взаимодействие процессов, проверок, бизнес-правил (механизм правил) в смысле, отличном от DDD?
Мне нравится луковая архитектура, и я могу использовать UI -> App Services -> Core -> Infrastructure, чтобы обеспечить четкое разделение задач. Но Ядром могут быть упомянутые выше соавторы, а не настоящие «концепции предметной области».
Часть меня считает, что в данном случае «концепции предметной области» ЯВЛЯЮТСЯ валидаторами, процессорами, бизнес-правилами, потому что они составляют вездесущий язык, о котором мы говорим, когда обсуждаем нашу систему. В этом случае у меня были бы Сущности без реального поведения (по большей части) и концепции предметной области в терминах Процессоров, Валидаторов, Механизма правил, которые реализуют поведение в системе.
Добавляем еще немного информации. Учитывая мой вопрос выше, я работал над решением, которое выглядело бы так:
org.example.app
org.example.domain - Сотрудник - Компания - EmployeeLevel
org.example.domain.shared - Процесс - BusinessRule - Валидатор
org.example.infrastructure
Надеюсь, этот небольшой фрагмент внесет немного ясности.
Итак, концепции Process, BusinessRule и Validator будут находиться внутри домена, но будут поддерживать модель предметной области с точки зрения того, что делает система.