聚合根包括大量的孩子

时间:2017-02-05 13:09:38

标签: domain-driven-design cqrs event-sourcing

我想知道如何使用DDD和CQRS对Calendar进行建模。我的问题在于增加了多少事件。我认为Calendar是包含事件(日历事件)的聚合根。我不想在我的命令中使用ReadSide,但我需要在域级别检查事件冲突。

2 个答案:

答案 0 :(得分:4)

  

我想知道如何使用DDD和CQRS对Calendar进行建模。我的问题在于增加了一些事件。

最常见的答案是"长寿"聚合是将这一生命分解为剧集。这方面的一个例子是会计师将在end of the fiscal year关闭的临时账户。

在您的具体情况下,可能不是"日历"和#34; 2月日历"," 3月日历"等等,在您的域名中适用任何粒度。

  

我不确定在验证方面我是否正确DDD aproach。我认为重点不是让模型进入无效状态

是的,但无效状态是一个棘手的事情。 Udi Dahan提供了this observation

  

时间上的微秒差异不应对核心业务行为产生影响。

更简洁地说,处理命令A后跟处理命令B产生一个有效状态,那么你最后应该首先处理命令​​B,然后是A。

让我们选择你的事件碰撞"例。假设我们处理两个命令scheduleMeeting(A)scheduleMeeting(B),并且域模型理解AB 碰撞。谜语:我们如何确保日历保持有效状态?

不失一般性,我们可以翻转硬币来决定哪个命令首先到达。我的硬币出现了尾巴,所以命令B首先到达。

on scheduleMeeting(B):
    publish MeetingScheduled(B)

现在,会议A的命令到了。如果您的有效日历不允许冲突,那么您的实现需要看起来像

on scheduleMeeting(A):
    throw DomainException(A conflicts with B)

另一方面,如果你认为命令到达的想法不会影响结果,那么你需要考虑另一种方法。也许

on scheduleMeeting(A)
    publish MeetingScheduled(A)
    publish ConflictDetected(A,B)

也就是说,日历聚合的建模不仅可以跟踪已安排的事件,还可以跟踪已出现的冲突。

另请参阅:aggregates and RFC 2119

答案 1 :(得分:3)

事件也可以是聚合根。我不知道你的业务限制,但我认为,如果两个事件合并,你可以通知用户以某种方式采取手动操作。否则,如果真的需要他们不要克服,你可以使用快照来加速巨大的日历AR。

  

我不想在我的命令中使用ReadSide,但我需要检查域级别的事件冲突。

您无法在aggregate命令处理程序中查询读取模型。对于colision检测,我会创建一个特殊的DetectColisionSaga订阅EventScheduled事件,并且如果发生了colision则会检查(可能是异步,如果有很多事件)并以某种方式通知用户。

相关问题