Domain driven design 域事件的粒度应该如何?

Domain driven design 域事件的粒度应该如何?,domain-driven-design,cqrs,event-sourcing,Domain Driven Design,Cqrs,Event Sourcing,我想知道域事件的粒度应该是多少 例如,我有一些简单的方法,比如在个人资料页面上更改名字、第二个名字和电子邮件地址。我应该有3个不同的域事件还是只有一个 通过粗粒度域事件,当我添加新功能时,我必须创建事件的新版本,因此我必须添加新的事件类型,或将事件版本存储在事件存储中。通过细粒度域事件,我没有这些问题,但我有太多的小类。您认为,在这种情况下,最佳做法是什么?很多类都有什么问题?真的,为什么这么多开发人员害怕有太多的类?您可以根据需要定义任意多的类 域事件表示域以某种方式发生了更改。它应包含所有相

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

例如,我有一些简单的方法,比如在个人资料页面上更改名字、第二个名字和电子邮件地址。我应该有3个不同的域事件还是只有一个


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

很多类都有什么问题?真的,为什么这么多开发人员害怕有太多的类?您可以根据需要定义任意多的类

域事件表示域以某种方式发生了更改。它应包含所有相关信息,并应考虑到事件也是DTO这一事实。您需要清晰的事件,但事件的粒度或通用性取决于开发人员


大小不是一个问题,但是如果您的事件“权重”为1MB,则可能您有问题。类的数量不是域事件设计标准。

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

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

在我的例子中:

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

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

  • 她的帐户被盗(安全问题,而非业务问题)
  • 她转到另一个电子邮件地址
  • 她结婚了
  • 她讨厌她以前的名字
  • 她故意把账目给了别人
  • 等等
嗯,如果我们有婚介服务,那么记录离婚可能具有商业重要性。因此,如果这些信息真的很重要,那么我们应该将其放入域模型中,并创建一个
userprobablydivoced
事件。如果它们都不重要,那么我们可以简单地说,她只是想更改她的个人资料页面,我们不关心为什么,因此我认为在这种情况下,
UserProfileChanged
UserSecondNameChanged
事件都是可以接受的

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


因此,总而言之,域事件的粒度应由域开发人员决定,但它应该受到业务角度的影响,而不仅仅是从建模和数据模式角度的影响。但我认为这是显而易见的,因为我们正在建模业务,而不仅仅是数据结构。

谢谢,粒度是我想要的词。“许多类有什么问题?”-为每个属性更改定义一个类对我来说有点奇怪。。。我不知道,这是一种直觉顺便说一句,有3-4个属性的小班是可以的,但是有一个只有一个属性的DTO对我来说是不好的。你能更具体一点吗?通过我给出的配置文件更改示例,您会怎么做?您不会为每个属性更改定义一个类,而是为每个域更改定义一个类,可以是1个或多个属性@MikeSW。我同意您的意见。我现在面临这种情况,对我来说,拥有细粒度事件似乎更符合逻辑。要考虑IMO的事情是事件类应该包含所有发生的细节,不多,不少。如果我们考虑“人”,那么我们可以定义一个包含n个字段或一个MyNeMeNealEngestEnter的PosialExchange命令。如果我们定义了一个包含许多字段的PersonChangedEvent,那么实际知道哪些字段已经更改可能会有问题。到目前为止,我更倾向于改名。但事实上,这一切都“取决于”:)你把事情弄得一团糟。CQR与事件源无关,但它们一起使用。您没有为ES设计域事件,因为您并不总是使用ES,我不同意事件应该总是表达用户意图。事件捕获域更改,而不管是什么触发了它们。PhoneNumberMigrated和PhoneNumberCorrected是从域的角度而不是用户的角度来看的。领域专家不是程序员,他不知道什么是命令/事件。在编写一行代码之前,开发人员将根据与领域专家的讨论来决定事件的结构。在我看来,这是一种过于僵化的方法。你知道,开发人员并不是那种只会大量编写代码的业务无知的猴子。开发人员必须在编码之前理解领域,但是开发人员不需要领域专家(除非他们是同一个人)。所以我必须说,开发商与此有着千丝万缕的联系。在DDD和CQR中,可能有一些地方这些法律并不总是有效的。这根本不是真的。此外,DDD、ES和CQR是不同的东西。“设计