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)事件被广播到正在监听的任何代码(代码可以对事件做出反应)。