DDD:一个根聚合保留对另一个根聚合的引用是否正确?


16

遵循域驱动设计(DDD)时,对于根聚合保留对恰好是单独聚合中根实体的内部实体的引用是否正确?

我认为这是不正确的,主要是因为这本关于蓝皮书的规则:

除了根ENTITY,AGGREGATE边界之外的任何内容都不能保存对内部任何内容的引用。根ENTITY可以将对内部ENTITIES的引用传递给其他对象,但是这些对象只能临时使用它们,并且它们可能不会保留引用。根可以将VALUE OBJECT的副本交给另一个对象,它发生什么都没有关系,因为它只是一个VALUE,不再与AGGREGATE有任何关联。

如果一个根聚合包含对另一个根聚合的引用,则违反了前者的边界,并且聚合的整个概念都已损坏,因此我认为,如果一个根聚合看起来像需要保留对另一个根聚合的引用,那么我需要创建一个不同的实体,该实体可能会与另一个根实体共享一些相同的成员,但不会具有全局标识,因为本书中的另一条规则指出:

根实体具有全球性。边界内的实体具有本地身份,仅在AGGREGATE内部具有唯一性。

我相信这将是正确的方法,但是由于它具有重复性和冗余性(当从纯DOP脱离DDD的上下文时),我要求提供一些反馈。


您所说的“内部实体(恰好是单独聚合中的根实体)”是什么意思?
埃里克·艾德

2
FWIW,任何事物都可以指代聚合根实体,因为这些是具有全局标识的事物;引荐来源本身是否是根实体并不重要。
埃里克·艾德

正如埃里克所说。另外,使用模型中的ID或引用来引用都没有关系。两者都将在数据库级别转换为ID,并且具有引用使ORM能够按需延迟加载实体。
欣快感'16

Answers:


21

您可能过度解释了这本书。它的基本含义是:聚合之外的任何内容都不能引用除根之外的任何内容。因此,引用根是合法的。持有对根的引用并不意味着它是您自己的集合的一部分,并且您可以控制其不变式。它保持自己的不变性和自治性。

然而,

  • 公认的良好做法是通过存储AR的ID而不是完整的引用来引用AR。
  • 更为现代的骨料设计方法(请参阅《红皮书》)主张骨料之间的分隔更加清晰。业务交易应仅更改单个聚合的状态。在这种假设下,存储对另一个聚合的引用的需求往往会消失,因为您不会同时修改两个聚合。

根聚合持有对恰好是单独聚合上的根实体的内部实体的引用是否正确?

这永远不会发生。值对象可以是多个聚合的一部分,但不能是实体。原因是,没有什么可以阻止您在聚合之间共享同一实体实例。假设实体实例E属于聚合实例A和B。由于DDD的前提是聚合是入口点,因此您可以加载A,并通过它来修改实体E,同时无声地违反了B(您没有加载)。

请参阅Greg Young的解答:http : //domain-driven-design.3010926.n2.nabble.com/Can-an-Entity-be-Shared-across-many-Aggregates-td7579277.html


谢谢Guillaume提供清晰,简洁和有见地的答案。真正的DDD鉴赏家的精湛技巧。这就是我想要的。开头语!
Lesair Valmont,

我知道这可能是一个愚蠢的问题,但是请问holding a reference在这种情况下这是什么意思?因为当您说那holding a reference to a root is legitThis never happens. A Value Object can be part of multiple Aggregates, but not an Entity. The reason is, nothing would then prevent you from sharing the same entity instance between Aggregates.
句话

1
保持引用=作为班级成员在内部/持久保存它。这里的二分法是根与非根。您可以保留根引用,但不能保留非根引用。
guillaume31 '18

@ guillaume31非常感谢,但是我能问一下是否可以将id内部实体(非根)保留在另一个聚合中,否则是否违反(根与否)?
Anyname Donotcare

您将如何处理该ID?甚至存储库也只能为您提供根,而不是内部实体。
guillaume31'9

1

您的聚合根对象(通常)应仅具有属于其域的属性。

如果您有一个AR对象的属性不在聚合中,那么您将立即面临这个问题。'为什么不?'

您可以添加另一个对象的ID吗?还是注入存储库?

但是听起来您应该添加一个跨域服务,该服务同时引用两个根对象并执行所需的逻辑


Ewan,我考虑的更多是在OOP的意义上重用两个不同聚合之间的类,而不是让域服务充当业务脚本来对两个不同DDD聚合做一些工作。总之,我同意你的看法,我的聚合根应该只具有属于其域的属性。
Lesair Valmont,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.