域事件应该多么精细?

时间:2014-05-23 15:25:41

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

我想知道域事件的粒度应该是多少?

例如,我有一些简单的事情,比如更改个人资料页面上的firstName,secondName和电子邮件地址。我应该有3个不同的域事件还是只有一个?

当我添加新功能时,粗粒度域事件,我必须创建一个新版本的事件,所以我必须添加一个新的事件类型,或在事件存储中存储事件版本。通过细粒度的域事件我没有这些问题,但我有太多的小类。您怎么看?在这种情况下,最佳做法是什么?

2 个答案:

答案 0 :(得分:11)

许多课程有什么问题?真的,为什么这么多开发者都害怕上课太多?您可以根据需要定义任意数量的类。

域事件表示域以某种方式发生了变化。它应包含所有相关信息,并应考虑事件也是DTO的事实。您需要明确的事件,但由开发人员决定事件的粒度或通用程度。

尺寸不是问题,但是如果你的事件“重量”1 MB,你可能会遇到问题。并且类的数量不是域事件设计标准。

答案 1 :(得分:9)

我同意MikeSW的回答,但在建模过程中应用SRP,你最终可能会得到小班,这根本不是问题。

根据Greg Young,域事件应始终表达用户从业务角度所做的事情。例如,如果用户有2个理由更改其电话号码PhoneNumberChanged,并且此信息从业务角度来看很重要,那么我们应该创建2个事件类型PhoneNumberMigratedPhoneNumberCorrected来存储技术上相同的数据。这显然违反了DRY,但这不是问题,因为在这些情况下,SRP可以通过在多个有界上下文之间共享聚合及其属性(最常见的是聚合ID)来覆盖DRY。

在我的例子中:

  

我有一些简单的事情,比如改变firstName ,.   secondName和个人资料页面上的电子邮件地址。

我们应该问以下问题:为什么用户会想要这样做,从我们的业务角度来看它有什么重要性吗?

  • 她的帐户被盗(安全,而非商业问题)
  • 她转到另一个电子邮件地址
  • 她结婚了
  • 她讨厌她以前的名字
  • 她故意将该帐户提供给其他人
  • 等...

好吧,如果我们有约会代理服务,那么记录离婚可能具有商业重要性。因此,如果此信息非常重要,那么我们应该将其放入域模型中,并创建UserProbablyDivorced事件。如果它们都不重要,那么我们可以简单地说,她只是想改变她的个人资料页面,我们不在乎为什么,所以在这种情况下我认为UserProfileChangedUserSecondNameChanged事件是可以接受的。

域事件可以与命令的1:1和1:n关系。通过1:1关系,它们的名称通常与命令相同,但是过去时。例如ChangeUserProfile -> UserProfileChanged。通过1:n关系,我们通常将命令所代表的行为拆分为一系列较小的域事件。

总而言之,域开发人员决定域事件应该是多么精细,但它应该从业务角度明显受到影响,而不仅仅是从数据架构的角度建模。但我认为这很明显,因为我们正在建模业务,而不仅仅是数据结构。