如果存储库在构建过程中相互通信,是否违反了任何领域驱动的设计原则?
例如,用户地址存储库与城市/地区/国家存储库对话以获取数据?
我认为它违反了领域驱动设计,存储库不应相互引用。此外,您不应在存储库与数据库表之间进行 1 : 1 映射。
这是 和 的Aggregate
概念AggregateRoot
。例如,假设数据库中有 2 个表:
Order
OrderLine
对于关系 1:n,(Order, OrderLine) 被定义为一个聚合,因为没有 Order,OrderLine 就不能单独存在。在这种情况下,Order 是这个聚合的根。
有了这个,而不是创建两个存储库:
OrderRepository
OrderLineRepository
你应该只有一个OrderRepository
来处理整个聚合,使用级联加载、插入和删除OrderLine
因此,在您的情况下,应该考虑您是否存在地址/城市/地区/国家存储库。
希望这有帮助
有几种方法可以解决您的问题:
保持 2 个聚合根之间的紧密关系,并在为第一个根补水时系统地为第二个根的整个聚合补水。这要求第一个存储库与第二个存储库对话,IMO 不会违反任何 DDD 原则,但在性能方面可能会出现问题。
将两个根松散地连接在一起。这基本上意味着指向被引用的根的 ID 而不是完整的实例。客户端代码或根本身(尽管有些人会说后者是不好的做法)然后将通过调用其存储库从其 ID 重新水化引用的根。
意识到诸如 City、Region 或 Country 之类的对象实际上是(不可变的)值对象,不需要 ID,并且可以由任何聚合根或实体直接引用,而不会产生进一步的后果。这也意味着这些对象没有存储库。
在选项 1 和 2 之间进行选择只是一个技术问题,只会影响性能和开发人员的舒适度。选项 3 更像是一个可能对业务产生影响的领域选择。用户可以创建、修改和删除城市、地区和国家大域实体吗?有专门的屏幕吗?这些是您在做出决定之前需要与您的领域专家讨论的问题。
您可能会发现有用的链接:
http://tech.groups.yahoo.com/group/domaindrivendesign/message/8696
我们在系统中遇到了与 ISO 货币和 ISO 国家相同的问题。我们发现,几乎我们拥有的每个聚合根(并具有相应的存储库)都需要将货币和/或国家实体作为子实体。从数据管理和数据检索的角度来看,这被证明是低效的,因此我们做了以下工作:
根据我的经验,DDD 和蓝皮书是一个非常宝贵的指南,但您不必 100% 准确地采用它,您可以接受建议,然后您对其进行调整以使其对您有意义。
希望这可以帮助 ...
出色地。DDD 中存储库的全部目的是抽象出数据源。如果您的用户地址需要完整的城市/地区/国家/地区,请使用这些存储库。
这种方法的问题是查询效率很低。
相反,在数据库中创建一个视图,该视图会加载包含所有必需信息的用户地址(或者使用您的 ORM,如果有的话)。
总结一下:
DDD 中没有任何内容规定您应该如何实现存储库。DDD很清楚,从repository加载的实体应该是完整的,不管信息如何存储在数据源中= repository只是定义为抽象层