我必须解决一个域问题,我对什么是更好的解决方案存有疑问。我将提出问题:
我有应用程序,每个应用程序有很多流程。 应用也有一些 ProcessSettings 。当我必须创建流程时,我有一些业务规则,例如,基于应用程序的流程设置,我必须在某些流程属性上应用一些规则。
我已将 Application 视为聚合根,将 Process 视为其他聚合根,并将ProcessSettings视为Application聚合内的值对象。
我有一个用例来创建流程,其逻辑是创建一个有效的流程实例并将其与ProcessRepository持久化。好吧,我想我有两个选择来应用流程设置:
您认为哪种方法最适合使用?还是以其他方式实现?
谢谢!
答案 0 :(得分:0)
我们的产品负责人告诉我们,如果客户在 片刻,并创建了一个流程,该设置将对此有效 如果客户端不更新它,则处理。如果客户离开支付 然后,当客户要更新该设置时, 系统不允许更新它,因为实际设置不会 适合过程数据
鉴于基于流程设置的验证仅在流程创建/更新方案中进行,因此这使实现更加容易。此外,我猜想竞争条件也与业务无关,例如,如果在创建/更新流程的同时更改设置。
鉴于此,我们可以假设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
执行间接IO。如果要避免这种依赖性,则可以引入诸如ProcessDomainService
之类的域服务来封装创建/更新逻辑,或者甚至可能认为查找逻辑不够复杂并将其直接放在应用程序层中。 / p>
//Application layer service
void createProcess(processId, applicationId, data) {
processSettings = processRepository.findByApplicationId(applicationId);
process = application.createProcess(processId, data, processSettings);
processRepository.add(process);
}
我们没有办法告诉您哪种方法在您的特定情况下更好,有时甚至没有一种完美的方法,许多其他方法可能同样有效。根据经验,保持聚合纯净是个好主意,因为单元测试更容易(减少模拟)。