我目前正在考虑域事件的粒度.据我所知,这是一个很好的模式,从命令到域事件的1:1关系开始,以便域事件表达用户所做的事情.
在我的例子中,有一段(火车或公共汽车)的旅程,包括一系列停靠点.这些停靠点中的每一个都会在发生时分配时间戳.现在,用户可以取消此旅程,从而导致所有时间戳从旅程的停靠点中移除(简化).
我要做的是发出一个"JourneyCancelled"事件.
现在,如果有一个读取模型提供了旅程的停靠列表 - 读取模型将如何处理此事件?它可能还会重置旅程中每个停靠点的时间戳,这意味着它会复制那里的逻辑(以及处理此事件的每个其他读取模型).
我感兴趣的是旅程被取消但我也对发生的细节感兴趣.
关于域名事件,我做错了什么?
罗尼
据我所知,这是一个很好的模式,从命令到域事件的1:1关系开始,以便域事件表达用户所做的事情.
重申 - 1:1是常见的,因为许多命令只修改单个实体而不需要任何补偿操作,但它不是通用的.当用户提出更改时,您通常需要多个事件来维护不变量.
您还要小心"用户所做的事情".如果您的消息描述了用户(在现实世界中)已经完成的事情,则该消息是事件,而不是命令.命令是用户要求模型做某事(重要的试金石 - 允许说不的模型吗?).
在我的例子中,有一段(火车或公共汽车)的旅程,包括一系列停靠点.这些停靠点中的每一个都会在发生时分配时间戳.
请记住,"聚合"几乎总是信息资源 - 不是Traveler,而是TravelerProfile.不是旅程,而是预订或行程.
在这种情况下,"何时会发生"意味着计划或行程作为一个概念,应该在您的模型中明确(尚不清楚这个东西是您的聚合的根,还是其中的子实体).
您还需要考虑停止(我喜欢Legs,来自我在旅行软件中的工作)是值,还是当前状态的entites.
现在,用户可以取消此旅程,从而导致所有时间戳从旅程的停靠点中移除(简化).
提示:在询问建模建议时,避免简化; 良好的建模需要理解约束.
为什么取消旅程应该从时间表中删除时间戳,这一点都不清楚.
试图猜测你想要的类比; 在航空旅行中,旅行由腿组成.如果我们取消行程,我们还要取消支付腿票,释放座位分配等等.
所以选择座位分配作为具体的例子; 取消行程意味着释放座位分配是一个不变的事实,因此应该有一个明确的事件,宣布座位分配已被取消(截至时间戳等).
所以阅读跟踪座位分配的模型应该是监听座位分配事件,并适当地(明确地)更新座位图,而不是监听JourneyCancelled并推断座位的变化(隐含).
换句话说,我们通过使事件流更加明确来逃避重复业务逻辑的陷阱.请注意我们免费获得的额外解耦:因为读取模型可以侦听特定于其关注的实体的事件,所以我们可以在写入模型中重新设计聚合,而不必担心对读取模型的影响.