聚合根包括大量 children

Aggregate Root including tremendous number of children

我想知道如何使用 DDD 和 CQRS 为日历建模。我的问题在于越来越多的事件。我将日历视为包含事件(日历事件)的聚合根。我不想在我的命令中使用 ReadSide,但我需要在域级别检查事件冲突的方法。

事件也可以是聚合根。我不知道您的业务限制,但我认为如果两个事件发生冲突,您可以以某种方式通知用户采取手动操作。否则,如果您真的真的需要它们不发生冲突,您可以使用快照来加速巨大的 Calendar AR。

I dont want to use ReadSide in my Commands but I need way to check events collisions at domain level.

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

I wonder how to model Calendar using DDD and CQRS. My problem consist in increasing number of events.

对 "long lived" 聚合最常见的答案是将生命周期分成几集。这方面的一个例子是会计师将在 end of the fiscal year.

关闭的临时账户

在您的特定情况下,可能 "the Calendar" 不如 "the February calendar"、"the March calendar" 等等,以适合您所在域的任何粒度。

Im not sure if Im right about DDD aproach in terms of validation. I believe the point is not to allow the model to enter into invalid state

是的,但无效状态很难定义。乌迪大汉提供 this observation

A microsecond difference in timing shouldn’t make a difference to core business behaviors.

更简洁地说,处理命令 A 后处理命令 B 产生有效状态,那么您也应该先处理命令​​ B,然后处理命令 A。

让我们选择您的 "event collisions" 示例。假设我们处理两个命令 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