事件溯源中的命令与事件

19

我了解命令和事件的区别,但在许多情况下,您最终会遇到冗余和两个基本相同的类之间的映射(ThingNameUpdateCommand,ThingNameUpdatedEvent)。 对于这些简单的情况,您是否可以/是否使用事件作为命令? 人们是否将所有命令和所有事件序列化到存储中? 对我来说似乎有点冗余。

2个回答

19

通常情况下,这种冗余是有原因的,你会想避免出现以下几种情况:

  1. 源事件在更改时必须进行版本控制,因为它们在聚合根恢复时被存储和重用(反序列化)。如果该类也用作消息,则会使事情变得有些尴尬。
  2. 耦合性增加,同一类现在被命令处理程序、领域模型和事件处理程序使用。将命令端与事件端解耦可以简化后续工作。
  3. 最后是明确性。 命令以请求执行某项任务的语言发出(通常是命令式的),而事件则表示已经发生的事情(通常是过去式)。如果你使用同一类来处理两者的话,语言就会变得混乱。

最终这些只是数据类,这不像是“困难”的代码。 对于一些简单的场景,例如代码生成,有方法可以避免一些打字错误。例如,我知道Greg以前使用XML和XSD转换来创建给定领域所需的所有类。

我认为对于很多简单的情况,你可能要质疑这是否真的是领域(即建模行为)还是数据。如果只是数据,可以考虑不要在这里使用事件溯源。下面是Udi Dahan关于如何拆分域模型的演讲链接,这样就不需要对所有内容进行事件溯源编程了。我现在也比较赞同这种思路。

http://skillsmatter.com/podcast/design-architecture/talk-from-udi-dahan


8

通过一些实例和特别是 Greg Young 的演示(http://www.youtube.com/watch?v=JHGkaShoyNs),我得出结论:命令是多余的。它们只是来自用户的事件,他们按了那个按钮。您应该以与其他事件完全相同的方式存储它们,因为这是您不知道将来是否需要在视图中使用的数据。您的用户确实将该项添加,然后稍后从篮子中删除,或者至少尝试删除。您可能会在以后想要使用此信息来在以后提醒用户。


2
我也倾向于这个方向。我读到了一些很好的观点,关于你希望事件包含完成工作所需的所有数据,特别是当这些数据可能来自没有历史表示的外部系统时。但你同样可以将这种良好的实践应用于命令。尤其是如果你想要创造非常DDD的东西,那么命令和事件之间就不应该有真正的区别。意图应该是清晰的,并且域外的历史数据应该被包含进来。 - Arwin
1
我仍然认为命令是冗余的。我只是称呼我的做法为函数式事件溯源。这是我的最新博客,介绍了使用ES和F# Elm作为完整系统的内容:http://anthonylloyd.github.io/blog/2016/11/27/event-sourcing - Ant
1
我认为对我来说不同的是使用FP而不是OO。ES与FP非常契合,因为总和类型是一种自然可扩展的事件模式。不变性也非常适用于ES。 - Ant
1
我认为用户命令可以被视为事件的另一个原因是,我将UI设计为具有本地数据,这些数据会被修改,并且这些修改会异步地作为命令/事件发送到后端。如果一切顺利,您将希望做出适当的响应,如果没有,则需要进行相应的处理。换句话说,我目前的想法是没有实质性的区别。 - Arwin
2
看看这个项目 - https://github.com/gregoryyoung/m-r 。它同时使用命令和事件。 - xhafan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接