6

如果存储库在构建过程中相互通信,是否违反了任何领域驱动的设计原则?

例如,用户地址存储库与城市/地区/国家存储库对话以获取数据?

4

4 回答 4

13

我认为它违反了领域驱动设计,存储库不应相互引用。此外,您不应在存储库与数据库表之间进行 1 : 1 映射。

这是 和 的Aggregate概念AggregateRoot。例如,假设数据库中有 2 个表:

Order
OrderLine

对于关系 1:n,(Order, OrderLine) 被定义为一个聚合,因为没有 Order,OrderLine 就不能单独存在。在这种情况下,Order 是这个聚合的根。

有了这个,而不是创建两个存储库:

OrderRepository
OrderLineRepository

你应该只有一个OrderRepository来处理整个聚合,使用级联加载、插入和删除OrderLine

因此,在您的情况下,应该考虑您是否存在地址/城市/地区/国家存储库。

希望这有帮助

于 2012-09-25T06:25:49.163 回答
1

有几种方法可以解决您的问题:

  • 保持 2 个聚合根之间的紧密关系,并在为第一个根补水时系统地为第二个根的整个聚合补水。这要求第一个存储库与第二个存储库对话,IMO 不会违反任何 DDD 原则,但在性能方面可能会出现问题。

  • 将两个根松散地连接在一起。这基本上意味着指向被引用的根的 ID 而不是完整的实例。客户端代码或根本身(尽管有些人会说后者是不好的做法)然后将通过调用其存储库从其 ID 重新水化引用的根。

  • 意识到诸如 City、Region 或 Country 之类的对象实际上是(不可变的)值对象,不需要 ID,并且可以由任何聚合根或实体直接引用,而不会产生进一步的后果。这也意味着这些对象没有存储库。

在选项 1 和 2 之间进行选择只是一个技术问题,只会影响性能和开发人员的舒适度。选项 3 更像是一个可能对业务产生影响的领域选择。用户可以创建、修改和删除城市、地区和国家大域实体吗?有专门的屏幕吗?这些是您在做出决定之前需要与您的领域专家讨论的问题。

您可能会发现有用的链接:

聚合根引用其他聚合根

http://tech.groups.yahoo.com/group/domaindrivendesign/message/8696

于 2012-09-26T11:58:41.970 回答
0

我们在系统中遇到了与 ISO 货币和 ISO 国家相同的问题。我们发现,几乎我们拥有的每个聚合根(并具有相应的存储库)都需要将货币和/或国家实体作为子实体。从数据管理和数据检索的角度来看,这被证明是低效的,因此我们做了以下工作:

  1. 仍然保持每个聚合根只有 1 个存储库的概念(如上面的 Cuong Le 的回答)
  2. 维护国家和货币数据的缓存 - 当从数据库中耗尽聚合根时,我们使用缓存来检索货币/国家信息

根据我的经验,DDD 和蓝皮书是一个非常宝贵的指南,但您不必 100% 准确地采用它,您可以接受建议,然后您对其进行调整以使其对您有意义。

希望这可以帮助 ...

于 2012-09-26T09:53:57.003 回答
0

出色地。DDD 中存储库的全部目的是抽象出数据源。如果您的用户地址需要完整的城市/地区/国家/地区,请使用这些存储库。

这种方法的问题是查询效率很低。

相反,在数据库中创建一个视图,该视图会加载包含所有必需信息的用户地址(或者使用您的 ORM,如果有的话)。

总结一下:

DDD 中没有任何内容规定您应该如何实现存储库。DDD很清楚,从repository加载的实体应该是完整的,不管信息如何存储在数据源中= repository只是定义为抽象层

于 2012-09-27T07:15:28.363 回答