DDD в настраиваемой системе, управляемой правилами

Простите за незнание, я новичок в 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 будут находиться внутри домена, но будут поддерживать модель предметной области с точки зрения того, что делает система.


person noplay    schedule 11.09.2012    source источник


Ответы (2)


Из Википедии:

Доменно-ориентированное проектирование (DDD) - это подход к разработке программного обеспечения для сложных нужд путем глубокой привязки реализации к развивающейся модели основных бизнес-концепций.

Я считаю, что валидатор, процесс, правило не являются вашими основными бизнес-концепциями. Это довольно распространенные программные абстракции.

Я не большой поклонник «стандартного» DDD, но для того, чтобы быть более «ориентированным на предметную область», ваш DSL и ваши правила на самом деле должны быть построены вокруг ваших бизнес-концепций, чтобы придать этому больше смысла.

Под капотом вы по-прежнему можете использовать валидаторы, процессы, менеджеров, исполнителей и т. Д., Но ваши DSL / правила будут более читабельными, если вы будете использовать в них бизнес-концепции, а не программные абстракции.

ОБНОВЛЕНО: поскольку вы используете Groovy для определения своего DSL, вы можете использовать функцию разрешения имен динамических методов Groovy и функции построения для создания удобочитаемых правил и классов. Также вы можете использовать принцип «соглашение важнее конфигурации», чтобы ввести некоторую логику. Например, в Groovy вы можете попытаться построить что-то похожее на:

if (employee is "promotable") {
  start "promotion" for employee
}

is будет методом в объекте базового домена, который будет проверять наличие, скажем, класса EmployeePromotableValidator, который сам по себе также может быть классом Groovy, использующим выразительность Groovy DSL.

class EmployeePromotableValidator extends Validator<Employee> {

  boolean validate(Employee employee) {
    employee.age > 25 && employee.workingYears > 2
  }

}

start будет методом в вашем сценарии базового правила, который будет искать класс EmployeePromotionProcess, который снова может быть классом Groovy.

Шаблон спецификации в этом случае очень прост, потому что он в основном становится частью языка:

if (employee is "promotable" && 
    employee is "advanced" && 
    employee.salary < 10000) {
  start( "salary increase", "10%" ) for employee
}

В общем, DSL с помощью (полу) функциональных языков, таких как Groovy / Scala, можно использовать для сокрытия абстракций программного обеспечения и придания большей видимости вашей бизнес-логике в коде. С простой Java вы получите много шаблонного кода, который в конечном итоге скроет все ваши намерения.

person Andrey Adamovich    schedule 12.09.2012
comment
Спасибо за ответ. В модели обязательно будут присутствовать бизнес-концепции (в следующем примере будет сущность «Сотрудник» и сущность «Компания» с соответствующими отношениями). Просто эти сущности по большей части будут голыми. Итак, если я правильно слежу за вами, то будут ли процессы, правила, валидаторы общими / общими в домене (в соответствии с шаблоном спецификации)? Это был путь, по которому я шел. - person noplay; 12.09.2012
comment
Спасибо за обновления. Я почти уверен, что бизнес-концепции будут центральными в модели предметной области. При настройке выполняется много работы, но существует множество основных бизнес-концепций, которые будут активны в домене. - person noplay; 17.09.2012

Это зависит от того, в чем именно состоит ваша бизнес-сфера.

Если вы создаете большой дополнительный настраиваемый crm, что-то, что-то конструктор делает все приложение - тогда ваш бизнес-домен делает это возможным, поэтому такие существительные, как Process, Executors и т. Д., Являются частью вашего домена.

Если вы создаете приложение, которое должно отслеживать информацию о сотрудниках и их продвижении по службе, тогда сфера вашего бизнеса - это сотрудники, зарплаты и показатели производительности. В этом случае относитесь к Process, Executors и другим подобным объектам как к злоумышленникам в вашем домене.

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

person Arnis Lapsa    schedule 13.09.2012
comment
Спасибо за вклад. Обычно я видел, как шаблон спецификации попадает в домен в общем пакете / контексте. Не будет обрабатывать, валидаторы и т. Д. al. тогда имеет смысл также попасть в область, аналогичную тому, что я видел со спецификациями? Я считаю, что реализация этих интерфейсов / базовых классов относится к инфраструктуре. - person noplay; 13.09.2012