当前位置: 首页 > news >正文

DDD 系列:事件风暴入门

上一篇文章中,我们学习了通用语言和上下文映射,知道了同一个限界上下文内要尽量使用统一的业务词汇,不同上下文之间也要明确协作关系。

不过,业务语言和边界并不是凭空设计出来的。真正开始做领域建模时,我们还需要和产品、业务、测试以及研发一起,把一段需求从头到尾梳理一遍。

这时候就会用到事件风暴。

**事件风暴是一种以业务事件为线索,通过多人协作梳理业务流程、业务规则和领域边界的建模方法。**它不是单纯开会,也不是把需求文档换成便利贴,而是让参与者围绕同一条业务流程持续讨论,直到关键概念和业务结果基本说清楚。

一、为什么需要事件风暴

我们平时接到一个需求,往往是产品先整理需求,项目经理再拆任务,开发根据需求文档写代码,测试最后根据页面和接口验证功能。

这个流程本身没有问题,但每次转述都可能发生一次理解偏差。比如产品说“用户下单后可以取消订单”,开发可能理解成修改订单状态,测试可能只验证未支付订单,而业务人员还认为已支付订单也应该支持退款。

最后大家使用的是同一个词,脑子里想的却不是同一个流程。

**事件风暴要解决的核心问题,就是把需求讨论从“描述功能”拉回到“发生了什么业务事实”。**大家不先讨论表结构和接口,而是先回答:业务过程中发生了哪些事件?是谁触发的?事件发生后还要做什么?有哪些规则会影响下一步?

这也和前面讲的通用语言、限界上下文有关。事件风暴过程中沉淀下来的业务词汇,可以作为通用语言的输入;事件和动作的聚集关系,也能帮助我们进一步识别业务边界。

二、事件风暴的基本元素

事件风暴通常使用不同颜色的便利贴表示不同类型的业务信息。颜色不是重点,重点是每种卡片都要表达一种明确的业务含义。实际使用时,团队可以约定自己的颜色,只要整场讨论保持一致即可。

1. 领域事件

领域事件表示已经发生的业务事实,通常使用过去式表达,例如:

  • 订单已提交;
  • 购车合同已签署;
  • 库存已锁定;
  • 退款已完成。

事件应该描述“已经发生了什么”,而不是“准备做什么”。“提交订单”是动作,“订单已提交”才是事件。

领域事件是事件风暴的中心。我们先把业务结果列出来,再围绕这些结果反推动作、角色和后续规则。

2. 命令或动作

命令表示希望系统执行的动作,它通常会导致某个领域事件产生,例如:

用户提交订单 -> 订单已提交 用户签署合同 -> 购车合同已签署 系统锁定库存 -> 库存已锁定

命令关注的是“谁要求系统做什么”,事件关注的是“做完之后发生了什么”。这两个概念不要混在一起,否则后面分析流程时很容易把待办事项和业务事实混为一谈。

3. 角色或执行者

角色是发起命令的对象,可以是用户、运营人员、系统任务,也可以是外部系统。

例如,用户点击提交按钮,用户就是执行者;定时任务关闭超时订单,定时任务就是执行者;支付平台通知支付成功,支付平台就是外部执行者。

4. 策略或业务规则

策略表示事件发生后,根据某些条件决定下一步动作的业务规则。

例如:订单支付成功后,如果订单包含分期商品,就创建分期计划;如果订单包含优惠券,就记录优惠券核销结果。

策略不只是技术上的if/else。它表达的是业务在什么条件下应该走哪条路径,后续可以继续拆成领域逻辑、应用服务编排或者外部系统协作。

5. 读模型

事件发生后,用户或者其他角色通常还需要看到某些结果,这部分展示数据可以先作为读模型记录下来。

例如“购车合同已签署”事件产生后,订单详情页需要展示合同编号、签署时间和合同状态,这些就是用户关心的查询结果。

读模型的重点是服务查询和展示,不要因为看到“模型”两个字,就马上把它和后面战术设计中的实体、值对象混在一起。本文这里只把它作为事件风暴中的分析结果来使用。

6. 外部系统

有些事件或动作并不属于当前系统,而是由外部系统参与完成。

例如当前系统发起扣款,支付系统返回扣款结果;当前系统通知合同平台保存合同,合同平台再返回签署结果。这些外部系统要单独标记出来,避免把别人的职责误认为当前领域内部逻辑。

事件风暴的最简链路可以理解为:

角色 -> 命令 -> 领域事件 -> 后续策略/命令 -> 新的领域事件

下面这张图把常用的卡片关系放在了一起,重点看事件如何成为流程的中心,以及规则、读模型和外部系统分别从哪里接入。

三、一次事件风暴怎么开展

事件风暴通常以 Workshop 的形式开展。参与者不一定越多越好,关键是要覆盖能够说明业务、验证业务和实现业务的人。

1. 准备参与人员

一般需要包括:

  • 熟悉业务流程的产品经理或业务人员;
  • 负责系统设计的架构师或技术负责人;
  • 参与开发的研发人员;
  • 负责验证流程的测试人员;
  • 必要时邀请运营、财务、客服或外部系统接口负责人。

这里需要注意,事件风暴不是开发人员自己画图。如果真正了解业务的人没有参加,最后很可能只是把开发人员的猜测贴到了墙上。

2. 准备场地和材料

可以准备一面白板、一块大画布或者在线协作工具,再准备不同颜色的便利贴。建议提前约定颜色含义,例如:

卡片类型示例作用
事件订单已支付表示已经发生的业务事实
命令支付订单表示希望系统执行的动作
角色用户、定时任务表示动作的发起者
策略支付成功后生成发票表示条件和后续规则
读模型订单详情表示需要查询或展示的数据
外部系统支付平台表示当前系统之外的参与者

颜色只是辅助记忆,卡片上的文字才是最终要讨论的内容。

3. 先确定业务目标

开始时不要急着讨论数据库表和接口字段,先把这次要梳理的业务范围说清楚。

例如本次只梳理“分期购车订单从提交到合同签署”的流程,那么支付对账、售后退款等后续流程可以先标记为边界外内容,避免一次会议把所有问题都混在一起。

4. 按时间顺序铺设事件

通常由产品或业务人员先讲一遍完整流程,参与者把听到的业务结果写成事件,再按照大致发生顺序从左到右排列。

这一步先求完整,不要一开始就纠结每个词是否完美。遇到不确定的地方可以先标记,后面集中讨论。

5. 围绕事件反推上下游

对每个事件依次追问:

  1. 这个事件之前发生了什么命令?
  2. 是谁发起了这个命令?
  3. 命令执行需要满足什么前提?
  4. 事件发生后,哪些策略会被触发?
  5. 后续动作由当前系统完成,还是需要外部系统参与?
  6. 用户或其他系统需要看到什么结果?

如果大家对同一个事件出现不同理解,不要直接选一个“看起来合理”的答案,而是把差异记录下来,回到业务规则本身继续确认。

6. 记录争议和未决问题

事件风暴的结果不是一次会议就能得到最终答案。对于暂时无法确认的问题,可以使用单独的标记记录下来,例如“待业务确认”“需要查看历史数据”“需要和支付系统负责人确认”。

**没有确认的业务规则,不要悄悄变成代码中的默认逻辑。**这类问题如果不记录,后面很容易变成“开发当时就是这么理解的”,再想追溯就比较麻烦了。

四、案例:梳理分期购车订单

下面以一个简化的分期购车订单为例,只演示事件风暴的思考方式,不展开完整的金融业务规则。

假设业务流程是:用户提交购车订单,订单审核通过后签署购车合同,合同签署完成后启动金融流程。

1. 先列出业务事件

按照时间顺序,可以先得到这些事件:

订单已提交 订单已审核 购车合同已签署 金融任务已启动

这些内容描述的是业务已经发生的结果,不是页面按钮,也不是数据库状态值。

2. 以“购车合同已签署”为中心反推

我们选中“购车合同已签署”这个事件,开始逐步分析:

  1. 产生这个事件的命令是“签署购车合同”;
  2. 命令的执行者可能是用户,也可能是合同签署系统,需要根据真实流程确认;
  3. 签署合同之前,订单必须已经通过审核,审核通过是这一步的业务前提;
  4. 事件发生后,合同平台需要保存签署结果,这是一个外部系统协作;
  5. 如果订单是分期订单,系统还要触发“启动金融任务”命令;
  6. 订单详情页需要展示合同状态、签署时间和合同信息,这些属于读模型。

用文字表示,流程大致如下:

订单已审核 | v 用户签署购车合同 | v 购车合同已签署 |-----------------------> 合同平台保存签署结果 | +-- 分期订单 ------------> 启动金融任务 | +-----------------------> 更新订单详情读模型

下面的案例图把这条链路和判断点画了出来。图中的“分期订单?”是业务策略,不是简单的技术分支;它说明事件发生后,不同订单类型会触发不同的后续动作。

3. 从事件聚集关系识别业务模型

继续观察上面的事件和命令,会发现“订单已提交”“订单已审核”“购车合同已签署”都围绕订单展开,命令的前提、状态变化和后续业务也主要由订单承载。

因此,我们可以初步把订单识别为一个业务聚集点。这里的“初步”很重要,事件风暴得到的是建模线索,不是直接生成最终 Java 类和数据库表。

后续还需要结合业务边界、数据一致性要求和团队对模型的理解继续确认。**不要看到几个事件都和订单有关,就马上把所有相关对象都塞进一个聚合。**聚合大小和边界属于后面战术设计要继续讨论的问题。

五、事件风暴和后续 DDD 设计的关系

事件风暴结束后,通常可以沉淀出几类结果:

  • 一组已经统一过含义的业务事件和业务术语;
  • 一条相对完整的业务流程和关键分支;
  • 参与流程的角色、外部系统和业务规则;
  • 可能的业务聚集点和领域边界;
  • 仍然没有确认的业务问题。

这些结果可以继续支撑后面的战略设计和战术设计:

  1. 用事件和术语补充通用语言;
  2. 根据业务流程和职责边界识别限界上下文;
  3. 结合一致性要求进一步分析实体、值对象、聚合和聚合根;
  4. 再根据模型结果设计代码结构和数据结构。

这里要分清楚一个边界:**事件风暴是分析和建模方法,不是自动生成代码的工具。**它能帮助我们把业务讨论变得具体,但最终模型仍然需要结合实际需求和实现成本反复调整。

六、总结

本文介绍了事件风暴的基本概念和一套可以落地执行的讨论流程。

简单总结一下:

  • 事件是核心,先描述已经发生的业务事实;
  • 命令表示要做什么,角色表示谁来做;
  • 策略表示事件发生后的业务规则和后续动作;
  • 读模型表示用户或其他系统需要看到的结果;
  • 外部系统要单独标记,避免把外部职责混入当前系统;
  • 通过事件、动作和规则的聚集关系,可以得到后续领域建模的线索。

事件风暴并不要求一次会议把所有模型都定死。真正重要的是让业务人员和研发人员围绕同一条流程把含义说清楚,把争议和未知记录下来。

下一篇文章我们进入 DDD 的战术设计,开始学习实体和值对象。到这里,DDD 的战略设计部分就暂时告一段落。

http://www.jsqmd.com/news/1177741/

相关文章:

  • 企业私有化部署网盘选型盘点:三款方案技术解析
  • 逻辑地址与物理地址转换:操作系统内存管理核心技术详解
  • PCL 基于欧几里得聚类的点云分割
  • Winhance:免费开源Windows系统优化工具的安全使用指南
  • Typora 跨版本(0.9.x-1.x)界面适配:解决4K宽屏下编辑区域过窄问题
  • 2026重庆黄金回收白银回收铂金回收靠谱临街实体公安备案支持到店核验门店联系方式推荐
  • Centos7配置国内yum源
  • ArcGIS Pro 3.2 三维地质建模实战:7步从钻孔数据生成MultiPatch地质体
  • AI医疗应用的技术边界与伦理实践:从视觉刺激到真实疗效
  • 金融数据分析入门:先学财报、指标还是工具?
  • BiliRoamingX:解锁B站完整观影体验的三大核心解决方案
  • 2026年7月最新江诗丹顿深圳罗湖万象城维修保养服务电话 - 江诗丹顿官方服务中心
  • 从Swagger手写到AI秒生成:ChatGPT驱动API文档升级(附GitHub高星开源工具链+校验脚本)
  • 社区居家养老服务平台开题报告
  • 从源码编译完整版Qt:包含QtWebEngine与QDoc的实战指南
  • PyInstaller 与 Nuitka 打包 EXE 逆向对比:2 种工具源码保护强度实测
  • Ubuntu下PlatformIO下载极慢?一招配置proxy,完美解决ESP32依赖包下载超时!
  • 用原生 JavaScript 实现一个基础代谢率(BMR)在线计算器:从公式到落地
  • 2.算法效率的核心密码:时间复杂度和空间复杂度详解
  • NestOS官网源代码解析:构建现代化容器主机操作系统网站的技术实践
  • 江诗丹顿官方换电池价格查询|热线及完整维修地址权威信息公告(2026年7月最新) - 江诗丹顿服务中心
  • Java Web人事管理系统实战:JSP+Servlet+MVC架构完整开发指南
  • 英伟达出手:通用机器人为何总在现实中「翻车」?
  • Nacos 2.3.2 Windows 单机部署:3步配置MySQL持久化与鉴权启动
  • openEuler hygon-kernel深度解析:国产海光处理器内核优化完全指南
  • GCC16倒逼C++生态升级:分层兼容架构与项目迁移实战
  • WeChat 与微信数据导出对比:2版本差异解析,通讯录等5类数据仅限海外版
  • OpenAI创始人奥尔特曼:至少到目前为止,我相当确信,AI总体上是在创造就业岗位
  • 影刀RPA 变量使用进阶:list-dict-自定义对象
  • 导师说论文有AI痕迹,有哪些真正亲测好用的的降AIGC软件推荐?