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

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

1 when and why使用领域事件?

1.1 定义

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

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


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

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


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

1.2 识别领域事件

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

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

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

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

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


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


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

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

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

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

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

image.png

聚合创建并发布事件

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

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


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


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


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

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

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


目录
相关文章
|
设计模式 前端开发 关系型数据库
【DDD】全网最详细2万字讲解DDD,从理论到实战(代码示例) 3
【DDD】全网最详细2万字讲解DDD,从理论到实战(代码示例)
5627 2
|
微服务 测试技术 Java
阿里技术专家详解 DDD 系列- Domain Primitive
关于DDD的一系列文章,希望能继续在总结前人的基础上发扬光大DDD的思想,但是通过一套我认为合理的代码结构、框架和约束,来降低DDD的实践门槛,提升代码质量、可测试性、安全性、健壮性。
62411 17
阿里技术专家详解 DDD 系列- Domain Primitive
|
Java API Apache
springboot 日志配置(logback)(一)
springboot 日志配置(logback)
1376 0
|
7月前
|
Ubuntu Windows
处理ubuntu启动过程中报错error:proc_thermal_add错误的方法
了解以上方法,就像寻找鬼屋出口的吊灯,当初见“error:proc_thermal_add错误”时的恐惧不翼而飞。各位Ubuntu使用者都是勇敢的探险家,遇到的问题无非是丛林中的野兽,尝试、努力和坚持总能找到解决的办法。
222 21
|
8月前
|
缓存 人工智能 监控
通义灵码进阶指南:解锁智能编程的隐藏技能
通义灵码是阿里云推出的智能编程助手,已突破简单代码补全功能,成为全栈开发导航仪、架构思维催化剂、代码质量监督员和知识检索加速器。本文从基础到进阶,详细介绍了其高效操作技巧,包括精准生成、对话式编程、代码重构及技术文档交互等功能。同时提供团队级最佳实践、专家级配置指南及避坑建议,并展望未来实验性功能。通过将其视为“编程伙伴”,开发者可实现更高效的人机协作,优化工作流并提升生产力。
535 6
|
11月前
|
SQL 存储 大数据
Flink 基础详解:大数据处理的强大引擎
Apache Flink 是一个分布式流批一体化的开源平台,专为大规模数据处理设计。它支持实时流处理和批处理,具有高吞吐量、低延迟特性。Flink 提供统一的编程抽象,简化大数据应用开发,并在流处理方面表现卓越,广泛应用于实时监控、金融交易分析等场景。其架构包括 JobManager、TaskManager 和 Client,支持并行度、水位线、时间语义等基础属性。Flink 还提供了丰富的算子、状态管理和容错机制,如检查点和 Savepoint,确保作业的可靠性和一致性。此外,Flink 支持 SQL 查询和 CDC 功能,实现实时数据捕获与同步,广泛应用于数据仓库和实时数据分析领域。
8146 32
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
415 5
|
存储 Java 测试技术
一文彻底搞懂阿里开源TransmittableThreadLocal的原理和使用
【10月更文挑战第2天】在Java多线程编程中,线程本地变量(ThreadLocal)是一个非常有用的工具,它能够在每个线程中保存一个独立的变量副本,从而避免多线程环境下的数据竞争问题。然而,在使用线程池等高级多线程技术时,ThreadLocal却面临着一些挑战。为了解决这个问题,阿里巴巴开源了TransmittableThreadLocal(TTL),它扩展了ThreadLocal的功能,使其能够在复杂的多线程环境中正确传递值。本文将深入探讨TTL的原理和使用,帮助读者彻底理解这一技术干货。
2193 0
|
存储 消息中间件 JSON
DDD基础教程:一文带你读懂DDD分层架构
DDD基础教程:一文带你读懂DDD分层架构
|
消息中间件 测试技术 领域建模
DDD - 一文读懂DDD领域驱动设计
DDD - 一文读懂DDD领域驱动设计
46058 6

热门文章

最新文章