如何处理事件源应用程序中的域更改?

Mar*_*Cid 3 scala event-sourcing

我目前正在使用Scala和Eventuate,但我认为这个问题适用于任何事件源环境:

比方说,你有以下事件:case class UserAdded(user: User)Usercase class User(username:String, birthday: Date).

您的应用已运行一段时间,现在您需要收集用户的电话号码.所以现在我们需要User改为case class User(username:String, birthday: Date, phoneNumber: String).

当重放事件时,它会抛出错误,因为过去的事件没有phoneNumber.您如何在事件源应用程序中解决此问题?

我的第一个想法是为事件存储中的所有事件设置默认值,但我知道当您进行事件采购时事件是不可变的,所以我决定听取更多有经验的用户的意见.

任何输入都非常感谢!

Fyo*_*kin 5

我认为这里存在两个概念错误.

首先,事件不应"引用"或"包含"域对象.事件是发生的事件的记录,因此它应该明确记录表征它的数据点.在这种情况下 - usernamebirthday:

case class UserAdded(username:String, birthday: Date)
Run Code Online (Sandbox Code Playgroud)

现在,这个事件定义永远不会改变.发生了什么,发生了.没有改写过去.

如果在某个时刻,业务需求发生变化,这意味着从现在开始会发生不同类型的事件:

case class UserAdded2(username:String, birthday: Date, phoneNumber: String)
Run Code Online (Sandbox Code Playgroud)

两个事件都应保持完好,两者都应该被处理,处理,等等.直觉可能暗示,第一个事件并非"现在无用".恰恰相反:第一个事件记录了需求变更之前发生的事情,并且该记录很有价值.

现在,根据您的平台允许的内容(我不熟悉Eventuate),您可以在技术上将两个事件实现为具有可选字段的单个类.但即使你这样做,你也应该永远记住这个类代表了两个不同的事件.出于这个原因,我宁愿将它们明确地定义为单独的东西.