Mar*_*Cid 3 scala event-sourcing
我目前正在使用Scala和Eventuate,但我认为这个问题适用于任何事件源环境:
比方说,你有以下事件:case class UserAdded(user: User)和User是case class User(username:String, birthday: Date).
您的应用已运行一段时间,现在您需要收集用户的电话号码.所以现在我们需要User改为case class User(username:String, birthday: Date, phoneNumber: String).
当重放事件时,它会抛出错误,因为过去的事件没有phoneNumber.您如何在事件源应用程序中解决此问题?
我的第一个想法是为事件存储中的所有事件设置默认值,但我知道当您进行事件采购时事件是不可变的,所以我决定听取更多有经验的用户的意见.
任何输入都非常感谢!
我认为这里存在两个概念错误.
首先,事件不应"引用"或"包含"域对象.事件是发生的事件的记录,因此它应该明确记录表征它的数据点.在这种情况下 - username和birthday:
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),您可以在技术上将两个事件实现为具有可选字段的单个类.但即使你这样做,你也应该永远记住这个类代表了两个不同的事件.出于这个原因,我宁愿将它们明确地定义为单独的东西.