域事件应该多么精细?

inf*_*rno 13 domain-driven-design cqrs event-sourcing

我想知道域事件应该是多么精细?

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

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

Mik*_*eSW 12

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

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

大小不是问题,但是如果您的事件'权重'1 MB可能您有问题.并且类的数量不是域事件设计标准.

  • 您没有为每个属性更改定义类,您可以为每个域更改定义一个类,该类可以是1个或多个属性 (4认同)

inf*_*rno 10

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

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

在我的例子中:

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

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

  • 她的帐户被盗(安全,不是商业问题)
  • 她转移到另一个电子邮件地址
  • 她结婚了
  • 她讨厌她以前的名字
  • 她故意把这个帐户交给别人
  • 等等...

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

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

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

  • 你搞砸了一些东西.CQRS与事件采购(ES)无关,但它们一起使用.您没有为ES设计域事件,因为您并不总是使用ES,我不同意事件应始终表达用户意图.无论是什么触发它们,事件都会捕获_Domain_更改.PhoneNumberMigrated和PhoneNumberCorrected是从Domain的角度而不是用户的角度.域专家不是编码员,他不知道命令/事件是什么.开发人员将根据与域专家的讨论来决定事件的结构 (3认同)