假设我们有class Home
并且我们希望在这个家中收集所有Cats
,但我们也希望拥有Cats
的通用存储库,其中包含所有猫世界。 Home
应该Cats
保留对{{1}}的特定存储库(或者可能是集合)的引用,还是应该在常规存储库中进行另一次查找?
答案 0 :(得分:3)
从域驱动的设计角度来看,您不应该在另一个AR实例中包含一个聚合根(AR)实例,并且通常也不会在任何实体中引用存储库。
因此,如果Home
和Cat
都是AR,则Home
应仅包含Cat
ID列表或值对象列表(VO),每个值代表一个猫,例如HomeCat
包含Id
,也许还包含Name
。这也有助于Home
AR周围的持久性,因为HomeRepository
将负责Home
和HomeCat
的持久性。
我必须承认,当Entity
Cat
包含在多个AR中时,HomeRepository
变得有些奇怪。但是,您仍然不会在主对象中拥有cat存储库,而是在检索相关的主实例时让CatRepository
使用{{1}}。
答案 1 :(得分:1)
由于Java基于引用,您可以保留两个集合而不会造成任何严重伤害。
您需要的是确保您家中的每只猫都在“世界”中。这里的问题是,如果您家中的猫变化很大,您需要进行多次查找,因此您应该选择数据结构数据,以便在需要时尽快启用(我在想hashMaps ..)
使用两个系列可以让您尽快找到家中的猫。然而,同步集合可能是一个问题。在这种情况下,你可以考虑观察者模式:家庭观察世界,如果猫死了,它检查它是否在家里,并删除......
有很多方法可以做你所要求的,所有你需要做的就是考虑更高频率的操作,以及你的需求。如果集合很小,那么有一个集合没有问题,查找猫找回家......
答案 2 :(得分:0)
很难回答虚构域名的DDD问题(或者至少很少有关于它的信息),因为DDD就是按照它的方式对域进行建模并保持域的完整性。不变式。
据我所知,您没有任何适用于Home
和Cat
之间关系的不变量,因此您不需要Cat
个Home
个对象的集合。 {1}}一致性边界。您可以简单地有两个聚合根(Home
和Cat
),Cat
将通过身份引用它Home
。
您可以使用CatRepository
查询来自特定家庭或所有猫的所有猫,而不管他们的家。
重要的是不要在模型中加入人为约束。例如,如果您在Cat
内保留Home
个身份的集合,除了维持关系之外没有其他原因,那么您将限制系统的可扩展性:两个同时发生的事务尝试关联新的Cat
1}}到同一个Home
将无故失败并出现并发异常(假设乐观并发)。
答案 3 :(得分:0)
如果Cat
需要是CatRepository
可访问的自己聚合的聚合根,那么{strong> <%}} 1}}聚合。您的Home
实体应按身份引用相关的Home
实体,而不是引用。
这是一个集合设计的问题,需要仔细查看您的域以及如何使用您的实体。您可以问自己的一个问题是“如果我删除Cat
,是否还应删除所有Home
个实体?”不要过分强调这个问题。还有其他重要因素需要考虑。
Vaughn Vernon在他的三部分PDF系列Effective Aggregate Design中介绍了这个主题。