DDD,可以在边界上下文中让多个聚合根共享同一身份吗?

时间:2018-06-21 16:42:49

标签: domain-driven-design aggregateroot bounded-contexts

在有限的上下文中可以有很多这样的聚合根吗

Product
   ProductID : GUID
   Name : string
   Price : float

ProductPromotion
   ProductID : GUID
   Discounted : float

ProductShortName
   ProductID : GUID
   ShortName : string

我不知道它们会破坏有界上下文规则,尽管它们是不同种类的产品,但是在上下文中。

link to my actual problem

2 个答案:

答案 0 :(得分:2)

在DDD方案中,每个聚合根都应该有其自己的唯一ID,并且似乎已经丢失了(如果我正确地理解了您的方案,则似乎您希望所有3个类都是根)。因此,如果您的设计遵循以下原则:

Product <ROOT>
   ProductID : GUID
   Name : string
   Price : float

ProductPromotion <ROOT>
   PromotionID: GUID
   ProductID : GUID
   Discounted : float

ProductShortName <ROOT>
   NameID: GUID
   ProductID : GUID
   ShortName : string

该设计本身不会损害总体或有限的上下文原则。应该允许一个聚合对另一个聚合根的ID进行引用(例如,在无数购物车示例中,LineItem包含对ProductID的引用)。

您不应该做的事情(看来您不是)正在完全引用另一个中的整个聚合。

但是,在设计聚合时,您应该始终反思自己的目标。是的,它们应该很小,但它们也必须传达一个目标。通常,它们被设计为强制执行某些不变量,而这些示例似乎并没有达到该目标。

虽然对于这个问题,您的示例可能过于简化,但我无法真正对其进行评估,但在我看来,“ ProductPromotion”和“ ProductShortName”似乎不是显示它们的完整汇总的理想选择。

答案 1 :(得分:0)

我已经在两个不同的应用程序中使用了该“模式”,并且效果很好。
我认为,如果您的集合内部有一个状态(其所有属性),则可以检查该命令可以工作的所有不变量。
如果要在聚合的命令方法中进行验证,则需要在另一个属性中存储属性,则会出现问题。
在另一个响应中,我读到每个聚合具有唯一的ID,在这种情况下,聚合的ID可以视为(AggregateType, GUID)
最后,您只是将单个聚合存储在多个分区中,这是一个一致性/事务边界的聚合,直到您的命令修改了原子操作存储的单个部分,您的聚合才不会违反任何规则。
为了了解是否适合您的问题,您还必须检查如何读取这些聚合,因为如果您需要读取整个聚合状态,则根据持久性技术的不同,您最终可能会对存储有多个查询以进行检索所有这些都会降低性能,这取决于您的用例(在我的情况下,其中一个是使用事件源开发的,因此,读取模型是作为单个读取操作完成的,在第二个中使用了一些缓存)帮助还执行多个查询,性能还可以)。