我想知道如何使用DDD和CQRS对Calendar进行建模。我的问题在于增加了多少事件。我认为Calendar是包含事件(日历事件)的聚合根。我不想在我的命令中使用ReadSide,但我需要在域级别检查事件冲突。
答案 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)
,并且域模型理解A
和B
碰撞。谜语:我们如何确保日历保持有效状态?
不失一般性,我们可以翻转硬币来决定哪个命令首先到达。我的硬币出现了尾巴,所以命令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)
也就是说,日历聚合的建模不仅可以跟踪已安排的事件,还可以跟踪已出现的冲突。
答案 1 :(得分:3)
事件也可以是聚合根。我不知道你的业务限制,但我认为,如果两个事件合并,你可以通知用户以某种方式采取手动操作。否则,如果真的需要他们不要克服,你可以使用快照来加速巨大的日历AR。
我不想在我的命令中使用ReadSide,但我需要检查域级别的事件冲突。
您无法在aggregate命令处理程序中查询读取模型。对于colision检测,我会创建一个特殊的DetectColisionSaga
订阅EventScheduled
事件,并且如果发生了colision则会检查(可能是异步,如果有很多事件)并以某种方式通知用户。