使用DDD和CRQS时,每个命令应该恰好是一个事件吗?


17

我正在寻找一种设计约定通用的ddd应用程序的方法。

说一个聚合“客户端”有一个定义为“ FillProfile”的命令。它将在逻辑上引发事件“ ProfileFilled”。

在某些情况下,命令会引发的事件多于一个事件,或者命令会基于某种逻辑引发不同的事件吗?还是这始终是1-1的关系(1个命令将始终不引发任何事件,或者仅引发给定类型的单个事件)。

我之所以这样问是因为,如果这是事实,那么命令将始终引发同一事件,那么我可以基于该事实建立约定系统。我知道“ RaiseEvent”将导致“ EventRaised” ...


1
如果命令导致2件事发生,则您可能希望每件事都会引发一个事件。ProfileGenerated,ProfileSaved,同样,任何事件都可能导致错误,并可能再次引发事件
Ewan 2015年

系统也可以轻松地实现BeforeCommand,AfterCommand等事件
Ewan

否则该命令可能会循环,即FillProfiles()profileFilled,profileFilled ....
Ewan

@Ewan,只想纠正您。域事件无法生成错误。只有命令可以。域事件表示发生某些事情,命令则表示有发生某件事的意图,该意图可以被拒绝或接受。换句话说,必须在派发域事件之前引发错误(当然,除非该域事件与错误记录有关)。
Ludovic C

Answers:


18

由于您用“ CQRS”标记了问题,所以我想您是指“ CQRS和事件源”上下文中的事件,如此处所述。在本教程中,事件和命令之间的区别得到了很好的解释:

  • 从系统的角度来看,事件捕获了系统中的基本“可能发生的事情”。

  • 从用户的角度来看,命令由用户认为是操作的定义

尽管这通常会导致一对一对一的命令和事件,但这些不同的观点可能会导致命令触发多个事件或根据命令参数而发生不同的事件。我什至可以想象命令根本不引发事件的情况,但这将是非常特殊的情况,而不是非常典型的情况。

例如,本教程提到事件

  • Tab打开
  • 订购饮料
  • 订餐

和命令

  • OpenTab
  • 下订单

在这里,命令“ OpenTab”将导致事件“ TabOpened”,但是命令PlaceOrder将导致事件“ DrinksOrdered”,“ FoodOrdered”或两者。

实际上,如果您是“从头开始”设计新系统,则可以尝试在命令和事件之间采用1:1对应关系进行设计,并查看系统变大时扩展的程度。您甚至可以尝试一种混合方法:具有1:1对应关系的事件和命令列表,以及一些其他组合命令。只需尝试将您引向要设计的特定系统的程度即可。


10

通常,一个命令将导致一个事件。但是在某些情况下,它也可以不止一个,这取决于您的实现。

您的命令会调用其他命令,每个命令都会触发自己的事件。或者您的命令自己执行不同的任务并发出多个事件。例如:

RegisterUserCommand

  • User.create(电子邮件,密码)→ UserCreatedEvent
  • User.updateProfile(firstName,lastName,location)→ UserProfileUpdatedEvent
  • User.joinDefaultGroup()→ UserJoinedGroupEvent

如果您以后决定拥有该UserWasAddedToCrm怎么办?重写整个流?
mcintyre321 '18

@ mcintyre321搜查编排VS精心策划的事件

10

一个命令可以引发多个事件。这只是一个事实的逻辑结论:Composite command存在。

假设您有两个命令,每个命令引发一个事件。然后,创建这两者的复合命令。从使用复合命令的一个角度来看,该命令似乎引发了两个事件。

因此,没有什么可以阻止您使用单个命令引发多个(甚至没有)事件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.