Domain driven design DDD如何在模型中生成唯一地址而不检查持久层?

Domain driven design DDD如何在模型中生成唯一地址而不检查持久层?,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,我的域中有一个地址模型,它有一些复杂的地址生成逻辑(想象一下类似于IBAN),但由于地址很短,可能会与数据库中存储的现有地址发生冲突。既然有一种既定的做法,即模型不应该访问存储库,那么如何实现这一点呢? 我是否应该在服务层创建一个实例,然后对照存储库检查它?从技术上讲,每个域用例都是一个服务。当您需要添加新的地址时,只需创建对象,然后验证是否存在类似的内容 在您的服务中,您可以使用查询来检查地址是否存在。如果希望它是一个存储库方法,那么它意味着Address是一个实体。但是,请注意,唯一性是一个

我的域中有一个地址模型,它有一些复杂的地址生成逻辑(想象一下类似于IBAN),但由于地址很短,可能会与数据库中存储的现有地址发生冲突。既然有一种既定的做法,即模型不应该访问存储库,那么如何实现这一点呢?
我是否应该在服务层创建一个实例,然后对照存储库检查它?

从技术上讲,每个域用例都是一个服务。当您需要添加新的
地址时,只需创建对象,然后验证是否存在类似的内容

在您的服务中,您可以使用查询来检查地址是否存在。如果希望它是一个存储库方法,那么它意味着
Address
是一个实体。但是,请注意,唯一性是一个业务约束,可能不应该隐藏在存储库中。我更喜欢在
CreateAddress
用例中清楚地表达出来

不过有一个陷阱,您服务中的所有内容都需要是幂等的。如果应用程序崩溃并且再次处理该命令,我们需要能够检测它是否是重复操作。无聊的。。这听起来很复杂,但一旦你做了一次就不难了


就我个人而言,我有一个“uniques”存储(恰好使用数据库来确保约束),在其中我放置了一个类似于[object\u type+unique\u property]的值,如果它存在,则返回false,如果不存在,则将其添加到存储中。它足够通用,可以与任何实体一起使用,而且它也是幂等的。

您可以通过多种方式处理它,但这取决于业务决策,因为总是需要进行权衡


通常最简单的解决方案是使用一种
地址生成服务
,它将触发
地址
的生成,选择结果并查询存储库以检查它是否存在。如果不是,则返回创建的
地址
,如果是,则选择查询返回的地址。这也可以在应用层(这是一种用例)而不是域服务中完成,这取决于您的特定体系结构。你必须记住,这不是100%防弹的。假设有人在您检查后和保存前生成了相同的地址。它会崩溃的。您必须与业务部门核实他们将如何处理它

您的意思是您将实现一个域服务,让它被称为
AddressFactory
,它将在引擎盖下使用
UniqueValueStore
以确保通过db约束的唯一性
UniqueValueStore
可以公开一个
add
方法,该方法将返回true或false,这取决于它是否能够根据约束在db中插入值。这是一个想法,但我会在创建地址的处理程序-用例-中直接使用存储。