我遇到的所有事件源系统案例(包括真实世界的案例和博客中考虑的示例场景(都假设事件在现实世界中发生的那一刻就存储在系统中。如果我们认为是技术或人为原因造成的延误怎么办?以一位员工为例,他正努力跟上桌上留下的笔记。他需要加上";过去的事件";。比如,";这发生在两天前,但还没有人在系统中标记它";
让我们考虑这样一个场景:;小型租车公司;应用事件将是:
- CarRented (rentalStartDate, ...)
- CarReturnedByCustomer (returnDate, odometerReading, milesDriven ...)
- CarServicedByMechanic (serviceDate, cost, ...)
该应用程序由公司的唯一员工使用。租车和还车时,他们会立即更新应用程序,因为该应用程序会生成打印给客户的文件等。然而,当汽车从维修中返回时,他们太忙了,无法立即标记,希望第二天再标记。或者可能与外部应用程序集成,在一夜之间发送一批每日数据。
基本上,我们最终会发现事件序列与事件发生的实际顺序不一致:
- CarRented (date: 2022-08-20)
- CarServicedByMechanic (date: 2022-08-16) <-- note the date here!
- CarReturnedByCustomer (date: 2022-08-22)
现在考虑跟踪";"自上次服务以来的里程数";每辆车:
On CarReturnedByCustomer: model.MileageSinceLastService += event.MilesDriven
On CarServicedByMechanic: model.MileageSinceLastService = 0;
这种预测在我们的场景中无法正常工作,因为事件与现实世界不协调。
你是如何处理此类案件的?这是针对此类场景使用ES的启发式方法吗?然而,当我想到这一点时,多个复杂的系统可能在某个时刻面临处理导入数据的需要,从而添加事件;后事实";
在事件源系统中,如何处理添加过去的事件?
在其他设计中处理过去事件的方式完全相同:建模时间。
这里的部分混淆是";事件";用来表示许多不同的想法;事件来源";为这个列表添加了更多的想法。
(很多这种情况都发生在"每个人"都熟悉这样一个事实的环境中,即环境中的微小变化会导致标签语义的巨大变化;但随后,这些标签逃到了整个社区,我们都了解到,重新使用标签实际上并不是一个好主意。(
我们不需要将事件("我们存储在持久存储器中的补丁文档的域特定表示"(与事件("携带来自域模型外部的信息副本的消息"(混淆。
本质上,你在这里发现的是两个想法:一个是你不能依赖消息到达";正确的";顺序
另一个是消息元数据(timeWritten、timeSent、timeReceived、timeProcessed(不是域数据(timeServiced(所必需的良好代理度量。
因此;右";答案是确保您的域消息携带了它们需要的所有信息,并确保您的领域逻辑包括正确集成这些新信息和已经写下的信息所需的分支。
但这些都是困难的部分;事件来源工作与您之前遇到的问题相同;好的,我们如何把这些变化写下来,以便以后记住&";。您是要使用补丁文档的新变体(也称为新的"事件"(还是重复使用您在生产中已经拥有的内容?
坏消息:无论是否使用事件源,您的设计都需要了解数据输入的性质。
例如,如果你的系统是为人们记下一堆笔记,然后将其作为一批输入的环境而设计的,那么在设计系统时,你需要思考其中的含义。
这台机器适合人。