1.去耦组件(微服务)

当组件A执行的逻辑需要触发组件B的逻辑时,不要直接调用它,我们可以将触发事件发送到事件分派器。组件B将侦听调度程序中的特定事件,并在事件发生时执行操作。

这意味着A和B都将取决于调度器和事件,但他们之间将不会知道对方存在,它们将被解耦。

理想情况下,调度员和事件都不应该在两个组件之间存在:

(1)调度员应该是完全独立于我们应用程序的库,因此使用依赖管理系统安装在通用位置。在PHP世界中,这是使用Composer等安装在vendor文件夹中的东西。

(2) 事件是我们的应用程序的一部分,应该在两个组件之间生存,组件之间通过事件进行通讯(结构上解耦,行为上耦合)。事件在组件之间共享,它是应用程序的核心部分。事件在DDD中属于共享内核Shared Kernel的一部分。这样,两个组件都将依赖于共享内核,但彼此不会意识到。然而在单体Monolithic应用程序中,为方便起见,可以将其放在触发事件的组件中。

DDD共享内核

[。..]明确界定指定团队同意分享的领域模型的一些子集。保持这个内核很小。[。..]这个明确共享的东西有特殊的地位,如果没有与其他团队协商,不应该改变。

Eric Evans 2014, 领域驱动设计参考

2.执行异步任务

有时候我们有一个我们想要执行的逻辑,但它可能需要相当长的时间来执行,我们不想让用户等待它完成。在这种情况下,希望将其作为异步工作运行,并立即返回给用户的消息,通知他请求将在以后异步执行。

例如,在网上商店下订单可以同步完成,但发送通知用户的电子邮件可以进行异步。

在这种情况下,我们可以做的是触发一个将被排队的事件,直到一个工作任务可以获得这个事件并执行它,只要系统有资源。

在这些情况下,相关联的逻辑是否在相同的有界环境中并不重要,无论哪种方式,逻辑都是去耦的。

3.跟踪状态变化(审计日志)

以传统的数据存储方式,我们拥有一些数据的实体。当这些实体中的数据发生变化时,我们只需更新数据库表行以反映新值。

这里的问题是,我们并不存储这些值为什么改变且什么时候改变。

我们可以将这些改变的事件存储在审计日志中。

更多关于这个进一步的前景,在关于事件溯源的解释。

事件模式

Martin Fowler确定了三种不同类型的事件模式:

(1)事件通知

(2)事件执行状态转移

(3)事件溯源Event Sourcing

所有这些模式共享相同的关键概念:

(1)事件是代表发生了一些事情(发生在某事之后);

(2)事件被广播到正在监听的任何代码(代码可以对事件做出反应)。