Владелец нашего продукта сказал нам, что если клиент мгновенно оплатил некоторые настройки и создал процесс, настройки будут действительны для этого процесса, если клиент не обновит его.Если клиент оставит платными некоторые настройки, тогда, когда клиент захочет обновить этот процесс, наша система не позволит обновить его, потому что фактические настройки не будут соответствовать данным процесса
Это делает реализациюнамного проще, учитывая, что проверка на основе параметров процесса должна происходить только в сценариях создания / обновления процесса.Кроме того, я бы предположил, что условия гонки также не будут иметь отношения к бизнесу, например, если настройки будут изменены одновременно с созданием / обновлением процесса.
В свете этого можно предположить, что 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);
}
Мы не можем сказать, какой подход лучше в вашем конкретном сценарии, а иногда нет даже идеального способа, и многие различные способы могут быть одинаково хорошими.Опыт показывает, что рекомендуется поддерживать чистоту агрегатов, так как это проще для юнит-тестов (меньше насмешек).