购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4
领域事件

现实中很多场景都可以抽象成事件,但凡在业务通用语言中出现“当……发生……时”“如果发生……”“当……时通知我”等描述时,我们就需要考虑是否要在这些场景中引入领域事件。领域事件就是把领域中所发生的活动建模成一系列离散事件。

在DDD中,对领域事件进行建模的核心在于明确事件的生命周期,如图2-19所示。

图2-19 领域事件的生命周期

可以看到,领域事件生命周期包括生成、存储、分发和消费4个阶段。而根据角色的不同,事件的生成处于事件发布阶段,而存储、分发和消费则可以被归为事件的处理阶段,如图2-20所示。

图2-20 领域事件的生命周期阶段示意图

把领域事件的处理过程分成两个阶段的目的是实现事件发布和处理的分离,从而确保实现不同的事件处理者。在第9章中讨论领域事件的具体实现过程时,我们会对DDD中采用的各种事件处理者展开详细讨论。

事件的识别有时候具有一定的隐秘性,当一个实体依赖于另一个实体,但两者之间并不希望产生强耦合,而我们需要保证两者之间的一致性时,通常可以提取领域事件,这是最典型的一种事件识别场景。例如,在电商类应用中,当系统生成一个订单时,我们可能需要发送一个通知给用户。在这个场景中,Order代表订单的聚合,而为了避免Order聚合与其他上下文之间产生强耦合,当Order对象被成功创建时,我们就可以提取一个OrderCreated事件。

领域事件同样需要建模,一般使用“聚合对象名+动作过去时”的形式对事件命名,如上述的OrderCreated事件。领域事件包含唯一标识、产生时间、事件来源等元数据,也可以根据需要包含任何业务数据。同时,领域事件具有严格意义上的不变性,在任何场合都不可能对事件本身进行修改,因为事件代表的是一种瞬时状态。

从架构设计上讲,对领域事件的处理就是基本的发布-订阅风格,如图2-21所示。

图2-21 事件的发布与订阅

在图2-21中,DomainEventPublisher和Domain-EventSubscriber分别代表事件的发布者和订阅者,DomainEvent代表领域事件。DomainEvent本身具备一定的类型,DomainEventSubscriber根据类型订阅某种特定的DomainEvent,这里是DomainEvent-Subscribe<OrderCreated>。

图2-22展示了领域事件涉及的领域对象及其交互时序图,我们可以看到应用服务ApplicationService对某个聚合对象进行操作会触发领域事件的生成,领域事件通过Domain-EventPublisher进行发布,DomainEventSubscriber则根据事件类型进行订阅和处理。

图2-22 事件的发布-订阅时序图

领域事件既可以由本地限界上下文消费,也可以由远程的限界上下文消费。远程限界上下文发布领域事件需要考虑消息的最终一致性、同步和异步机制以及领域事件存储等问题。尤其针对远程交互本身存在的网络稳定性等各种不可控因素,一般都会对事件进行存储,以便在发生问题时能够跟踪和重试。

关于事件的存储,我们也有一些常见的需求,包括支持不同事件类型,支持领域事件和存储事件之间的转换,检索由领域模型产生的所有事件的历史记录,使用事件存储中的数据进行业务预测和分析等。事件可以通过DomainEventPublisher进行集中式存储,也可以分别保存在各个DomainEventSubscriber中。图2-23展示了一个包含事件存储的发布-订阅时序图。

图2-23 包含事件存储的发布-订阅时序图

可以看到这里通过DomainEventSubscriber构建事件存储器EventStore进行专门的事件存储。 2CFjEq1S5R30G5vY8oOSlJjDY8MbpQKfVH2ptmyUpuFZPcp5Hla08cOBQP/9nuf0

点击中间区域
呼出菜单
上一章
目录
下一章
×