在DDD中引用另一个聚合根时考虑聚合根的一致性

时间:2017-09-29 23:16:42

标签: domain-driven-design consistency aggregateroot

在DDD中,聚合根可以通过直接对象引用(或指针)或通过标识引用另一个根。

此外,DDD意味着聚合根必须确保不变量和整个聚合边界的一致性。但是当我阅读vaughn vernon的书时,他提到他在谈论设计产品和 BackLogItem 聚合:

  

DDD声明一个聚合可能包含对其他根的引用   但是,我们必须记住,这并没有放置   引用聚合在一个一致性边界内   引用它。

我是DDD的新手,我认为BackLogItem通过引用Product聚合根来聚合root,它成为它的一个孩子,并确保它的一致性是BackLogItem的责任,例如如果产品被暂停,我们无法计划新的BackLogItem(我知道这个例子可能不是基于Scrum的应用程序的情况)。

所以我的问题是:应该确保BackLogItem聚合中的Product的一致性是Product还是BackLogItem聚合根?

1 个答案:

答案 0 :(得分:1)

  

在DDD中,聚合根可以通过直接对象引用(或指针)或通过标识引用另一个根。

是的,这与Eric Evans在2003年推出该模式的方式一致。

  

所以我的问题是:应该确保BackLogItem聚合中的Product的一致性是Product还是BackLogItem聚合根?

这个问题有点扭曲 - 我们不会尝试跨越聚合边界强制立即保持一致。

换句话说,如果积压项目和产品不一致时为expensive to the business,那么我们会重新设计模型,以便这两个实体属于同一个聚合

另一方面,如果业务昂贵;因为这不是什么大不了的事,或者因为它很容易修复;然后我们可以保持将这些实体放在单独的聚合中的设计,但接受我们检测和修复不一致,而不是阻止它们。

例如,如果用户界面只允许为未暂停的产品规划新的积压项目,那么我们只会遇到问题,如果产品在UI正在查看的产品的更新和到货之间暂停计划新项目的消息。

Udi Dahan提出了这样的框架:如果计划新的积压项目的消息在产品暂停之前几毫秒而不是之后几毫秒出现,那对业务真的很重要吗?如果确实如此,那么涉及一个的每个交易都必然涉及另一个。如果没有,那么就不要强迫它。

如果域模型不负责做出决定,那么您需要非常小心实施的一致性。请参阅Greg Young对warehouse systems的讨论。在您的具体示例中,将项目添加到积压的决定可能来自 person ,而不是来自域模型本身;同样,暂停产品的决定也来自一个人。记录两个决策并检测它们是否存在冲突通常是有意义的,而不是试图让模型否决已经做出的决定。 (注意:即使您认为产品和积压项目属于同一聚合,您可能仍希望这样做。)