DDD О дизайнерском решении - PullRequest
0 голосов
/ 20 марта 2019

Я должен решить проблему с доменом, и у меня есть некоторые сомнения относительно того, что является лучшим решением. Я собираюсь представить проблему:

У меня есть Приложения, и у каждого Приложения есть много Процесс . Приложение также имеет некоторые ProcessSettings . У меня есть некоторые бизнес-правила, когда мне нужно создать процесс, например, на основе параметров процесса приложения, я должен применить некоторые правила к некоторым свойствам процесса.

Я рассмотрел Приложение как корень агрегата и Процесс как корень другого агрегата, а ProcessSettings как объект значения внутри агрегата приложения.

У меня есть сценарий использования для создания процессов, и логика состоит в том, чтобы создать действительный экземпляр процесса и сохранить его с помощью ProcessRepository. Ну, я думаю, у меня есть два варианта применения настроек процесса:

  1. В случае использования получите параметры процесса из агрегата приложений по ApplicationId через доменную службу в агрегате приложений и передайте ProcessSettings в метод создания процесса.
  2. В случае использования для создания процесса и через доменную службу в Агрегате приложений передайте копию процесса (объекта значения), чтобы применить параметры процесса.

Какой подход, по вашему мнению, является наиболее правильным для использования? Или вы реализуете его по-другому?

Заранее спасибо!

1 Ответ

0 голосов
/ 21 марта 2019

Владелец нашего продукта сказал нам, что если клиент мгновенно оплатил некоторые настройки и создал процесс, настройки будут действительны для этого процесса, если клиент не обновит его.Если клиент оставит платными некоторые настройки, тогда, когда клиент захочет обновить этот процесс, наша система не позволит обновить его, потому что фактические настройки не будут соответствовать данным процесса

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

В свете этого можно предположить, что ProcessSettings и Process могут находиться в разных границах согласованности.Другими словами, оба могут быть частью отдельных агрегатных корней.

Кроме того, важно признать, что проверка на основе настроек не является инвариантом Process, то есть Process не должна отвечать за принудительное применениеэти правила себя.Поскольку они не являются инвариантами, вам также не следует стремиться к всегда действующей стратегии и использовать вместо нее отложенную стратегию проверки.

С этого момента существует много хороших способов моделирования этого варианта использования, которые все будут кипеть.вплоть до:

//Application layer service
void createProcess(processId, applicationId, data) {
    application = applicationRepository.applicationOfId(applicationId);
    process = application.createProcess(processId, data);
    processRepository.add(process);
}

//Application AR
Process createProcess(processId, data) {
    process = new Process(processId, this.id, data);
    this.processSettings.ensureRespectedBy(process);
    return process;
}

Если ProcessSettings являются частью Application AR, то может иметь смысл поместить фабричный метод в Application для создания процессов, если он содержит необходимое состояние длявыполнить проверку, как в приведенном выше примере.Это устраняет необходимость введения выделенной доменной службы для задачи, такой как автономная фабрика.

Если ProcessSettings может быть собственным агрегированным корнем, вы всегда можете сделать то же самое, но ввести домен поискасервис для настроек:

//Application AR
Process createProcess(processId, data, settingsLookupService) {
    process = new Process(processId, this.id, data);
    processSettings = settingsLookupService.findByApplicationId(this.id);
    processSettings.ensureRespectedBy(process);
    return process;
}

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

//Application layer service
void createProcess(processId, applicationId, data) {
    processSettings = processRepository.findByApplicationId(applicationId);
    process = application.createProcess(processId, data, processSettings);
    processRepository.add(process);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...