vlambda博客
学习文章列表

事件消费者之 Reactor - 事件溯源

Reactor(反应机)与 Projector[1] 大同小异,唯一的区别在于我们不能重播 Reactor 的行为。所以 Reactor 生为处理领域中有副作用(side-effects)的行为。

那么何谓有副作用的行为呢?如果一个行为发生一次与发生多次所产生的结果不同的话,此行为可理解为有副作用。比如当订单完成(OrderConfirmed)时给用户发送一封邮件,此行为有副作用,因为重播订单完成事件(OrderConfirmed)时,用户将收到重复邮件。

以下是从我们的实战经验中总结出来的 Reactor 用例。

实战用例

副作用行为

处理领域内有副作用行为是 Reactor 最直观的用例。比如发送订单邮件:

聚合间通信

有时候两个聚合间需要通过事件通信来完成一个简单的流程,这个时候我们可以使用 Reactor。假设我们建立了两个聚合,Order 和 Bill。当 Order 确认时,Bill 会自动生成一张 Invoice,我们可使用 Reactor 来完成这两个聚合间的通信:

这里需要强调此流程的简单性是有原因的。如果一个流程是复杂长时的话,我们应该采用 Saga 方案,因为它支持回滚操作。

翻译领域事件

事件溯源与其它架构模式混合使用时,我们不免要处理跨架构间的通信,这个时候我们可使用 Reactor。比如在 CRUD 架构中也需要监听事件溯源中的领域事件,如果我们在 CRUD 直接监听,就会出现抽象泄漏的情况(领域事件是事件溯源中的抽象概念)。这个时候我们可以使用 Reactor 将领域事件翻译成 CRUD 中的事件并发送出去:

总结

Reactor 好比一种特殊的 Projector。和 Projector 一样,它的职责单一且专注,易于编写单元测试。

References

[1] Projector: https://codedecoupled.com/php-es-projector.html