2017-05-05 516 views
0

在我的情况下,我有两个主要概念:用户(系统的主要公民)和组。 集团有两个子集合:等级和角色。没有团队,等级和角色就没有意义。 当用户被分配到该组时,我们还必须选择1个角色和1个等级,并将其分配给用户和组之间的这种关系。DDD:选择聚合根

Diagram

问:

多少总根吗,我这里?从用户方面来看,它显然是一个用户(系统的主要概念),但它与组的关系呢? AFAIK由DDD的规则禁止引用聚合根之外的实体。

回答

0

AFAIK由DDD的规则禁止引用聚合根外的实体。

嗯,我不会说这是“DDD的规则禁止”......有些时候你别无选择。我必须考虑与根集合关联的“实体”集合的大小。有时您可以在相同的聚合中维护关联,并使用某种“延迟加载”来避免资源消耗。弗农的iDDD书[1]围绕这个具体案例提供了一些建议和使用案例。看看他的博客文章[2]

[1] https://www.amazon.com.br/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577 [2] https://vaughnvernon.co/?p=838

+2

或者可以使用最终的一致性 –

0

你至少有以下选择,这取决于你的业务需求方面的一致性:

  1. 您有5个聚合根:用户,组,排名,角色和UserAssignment。最后一个必须保护不变“我们还必须选择1个角色和1个等级”。对于终身管理,您可以使用AR之间的最终一致性。例如,当您删除一个组时,您还必须删除孤儿排名,角色和用户分配。

  2. 你有用户(UserAssignment作为嵌套实体)和Group(角色和秩作为嵌套实体)。您在AR中具有很强的一致性(当您删除用户时,其所有分配也会被删除)以及用户和组之间的最终一致性。

你应该使用什么?只有你可以决定。例如,如果您选择第一个选项并删除用户,则可能会延迟几秒/分钟/小时,然后其分配也被删除。

由于价格并不便宜,所以应使用强力套牌保护业务不变式real

P.S.如果您需要从另一个AR中引用嵌套实体,那么您应该重新考虑您的聚合根边界,因为您的设计很可能是错误的。

+0

基本上,没有其父组,两个角色和等级都没有意义。它就像: “你好,我是国王[角色]。” “什么[群]的王?”。 “NullPointerException”。应用程序本身非常以用户为中心,一切都围绕用户的概念发展。在第二种选择中,碰巧我们有2个聚合 - 用户和组,对吗?但用户分配(用户实体中的嵌套实体)引用组聚合中的嵌套实体。这是你的意思还是我不了解你? –

+0

然后使用选项1和2的组合。我还试图让您理解如何思考设计聚合:一致性边界。没有绝对的答案。 –

+0

我们可以尽可能多地讨论,以便了解,但没有人可以确切地告诉您该做什么 –

0

我要改变一些的话,我们将看看是否有帮助(假设):

我有一个OrderProduct。当我将Product添加到Order时,我必须选择一个StoreColour

你会如何模型?

Colour很可能是一个Value Object,但Store不是。我会选择一个OrderItem值对象,其中包含一个Colour值对象和一个StoreId值来捕获关系。 Order将包含OrderItem条目的列表。

删除Colour条目没问题,因为我们已将该位非规格化到OrderItem。我们可能有另一个值对象代表Store,但通常我们不会删除存储或有一些处理来处理删除,或者更典型的,使用参照完整性约束来防止删除已使用的Store

如果您考虑删除Order,则只会删除OrderItem关联。

在你的情况UserGroup可能是总根源,我想补充一个UserGroup(或UserAssignment为康斯坦丁使用)。 UserGroup包含关联和相关位。你将不得不确定真正的域名结构。