DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(上)

简介: DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(上)
  • 如何将领域事件建模成对象,何时应该为领域事件创建唯一的身份标识?
  • 哪些组件用于发布事件,哪些组件用于订阅事件
  • 为什么我们需要一个事件存储?如何实现事件存储、如何使用事件存储?
  • 如何通过不同的方式将领域事件发布给自治系统

1 when and why使用领域事件?

1.1 定义

使用领域事件时,首先就是要对不同事件进行定义。

《领域驱动设计》并未给出领域事件的定义,因为该模型是在该书出版后才被提出。


当前对领域事件的定义:领域专家所关心的发生在领域中的一些事件。将领域中所发生的活动建模成一系列的离散事件。

每个事件都用领域对象来表示,领域事件是领域模型的组成部分,表示领域中所发生的事情。


如何确定哪些事件对领域专家重要?

1.2 识别领域事件

  • “当……”
  • “如果发生……,则……”
  • “当做完……的时候,请通知……”
  • 这里的通知本身并不构成一个事件,只是表明我们需要向外界发出通知.

在这些场景中,若发生某种事件后,会触发进一步操作,则该事件很可能就是领域事件。

有时从领域专家话中,好像也还看不出哪里有领域事件,但业务需求依然可能需要领域事件。领域专家有时可能意识不到这些需求,只有在经过跨团队讨论后才意识到这些。

之所以会这样,是由于领域事件需发布到外部系统,如到另一个限界上下文。由于这样的事件由订阅方处理,它将对本地和远程上下文都产生影响。

由于领域事件需要发布到外部系统,如发布到另一个限界上下文。这样的事件由订阅方处理,影响本地和远程上下文。


一个领域事件将导致进一步业务操作,在实现业务解耦同时,还有助于形成完整的业务闭环。


领域事件可以是业务流程的一个步骤,如一个事件发生后触发的后续动作:密码连续输错三次,触发锁定账户的动作。

领域事件为何要用最终一致性,而非SOA直接调用?

因为聚合的一个原则:一个事务中最多只能更改一个聚合实例,所以:

  • 本地限界上下文中的其他聚合实例,可通过领域事件的方式同步
  • 用于使远程依赖系统与本地系统保持一致

解耦本地系统和远程系,有助提高双方协作服务的可伸缩性

image.png

聚合创建并发布事件

  • 订阅方可先存储事件,然后再将其转发到远程订阅方
  • 或不经存储,直接转发
    除非MQ共享了模型的数据存储,不然即时转发需要XA(两阶段提交)。
  • 系统业务低峰期,批处理过程通常进行一些系统维护工作,如删除过期对象、创建新对象以支持新业务需求或通知用户所发生的重要事件。

这样的批处理过程通常需复杂查询&&庞大事务。若这些批处理过程存在冗余会怎样?


系统中发生的每一件事情,都用事件形式捕获,然后将事件发布给订阅方处理,能简化系统吗?


肯定的!它可消除先前批处理过程中的复杂查询,因为我们能够准确知道在何时发生何事,限界上下文也由此知道接下来应该做啥。在接收到领域事件时,系统可立即处理。原本批量集中处理的过程可以分散成许多粒度较小的处理单元,业务需求也由此更快满足,用户也可及时进行下一步操作。


领域事件驱动设计可切断领域模型之间的强依赖。

事件发布完成后,发布方不必关心后续订阅方事件处理是否成功,即可实现领域模型的解耦,维护领域模型的独立性和数据一致性。

在领域模型映射到微服务架构时,领域事件可解耦微服务,微服务间的数据不必要求强一致性,而是基于事件的最终一致性。


目录
相关文章
|
canal 消息中间件 存储
DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(中)
DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(中)
819 0
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
254 1
|
Kubernetes 前端开发 架构师
DDD as Code:如何用代码诠释领域驱动设计?(1)
DDD as Code:如何用代码诠释领域驱动设计?
186 0
|
IDE Java 程序员
DDD as Code:如何用代码诠释领域驱动设计?(2)
DDD as Code:如何用代码诠释领域驱动设计?
254 0
|
前端开发 API 网络架构
DDD as Code:如何用代码诠释领域驱动设计?(3)
DDD as Code:如何用代码诠释领域驱动设计?
167 0
|
测试技术 领域建模 微服务
DDD领域驱动实战(二)-限界上下文(bounded context)
DDD领域驱动实战(二)-限界上下文(bounded context)
316 0
DDD领域驱动实战(二)-限界上下文(bounded context)
|
Kubernetes 前端开发 Java
DDD as Code:如何用代码诠释领域驱动设计?
相较于常规的MVC架构,DDD更抽象、更难以理解,各个开发者对DDD的解释也不尽相同。那么哪种设计方式才更好?在学习时如何知道哪种DDD更正统,没有被别人带歪?本文尝试使用“DDD as Code”的概念,即用DSL代码方式来描述DDD,统一DDD的设计思想,通过案例详细介绍如何基于ContextMapper来完成一个项目基于DDD DSL的表达,并分享现实中DDD的设计流程和微服务的关系。
6017 2
DDD as Code:如何用代码诠释领域驱动设计?
|
消息中间件 前端开发 数据管理
DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(下)
DDD领域驱动设计实战(六)-理解领域事件(Domain Event)(下)
668 0