事件风暴工作坊
背景
什么是事件风暴
事件风暴是一种以协作探索复杂业务领域为目标的,灵活的工作坊(workshop)形式的活动。
一套管理复杂软件系统多人协作的步骤和方法,最大可能的让所有人参与表达、专注、思考,促成有效沟通。
事件风暴有什么价值
辅助应用架构设计。
通过事件风暴设计出命令,定义命令的业务本质。 识别命令的actor(定时job,人,外部系统), 识别命令对聚合的影响。 再基于聚合内部的数据结构和行为,明确具体的实体。
能够很清晰把负责项目主流程分析清晰。
借助事件风暴,能够把整个流程窜起来,识别
领域模型抽象。
方法1: 基于流程框架,适合复杂业务。 基于L5,L6,L7 (业务活动,任务,步骤,规则)抽象出业务对象。 再把L3、L4产生的业务对象看看语义相似性,是否可以合并。
方法2: 使用事件风暴。 团队没有出整理L5,6,7流程(因为偏好等原因),可以直接基于事件风暴识别聚合。
聚合的抽象,不是一蹴而就。需要基于业务场景做验证。基于业务流程的概念
事件风暴的例子:
初期
订单下单,订单评审 -- 抽象出订单作为聚合(或者业务对象)。
集合实际业务: 客户下1000台,可能部分有货先评审。 发现只有一个订单是不行的。 所以要拆成 客户订单(SCO)-- 客户的需求,和销售订单(SSO)-- 对SCO的履约 (V1)。
中期(需求变的更复杂)
- 订单下1000台,500台有货先评审先发,另外500台推送OFP走生产工单。
- 欧洲客户下一年的母单。当有货的时候,评审一点,发一点。
发现用客户订单和销售订单无法满足需求,原有的客户订单会变得很复杂。 比如MTO模式,
交易订单(原始需求): 生产,或者生产+发货,外部系统的订单
客户订单(发货需求)
销售订单(履约)
整个单据流变成 交易订单 --> 客户订单 --> 销售订单
快速梳理长流程的业务流程。
当业务涉及多个系统、异步事件、长周期流程(如电商订单、物流跟踪、风控审核)时,传统流程图可能变得极其复杂,而事件风暴用事件流更清晰。
当要探索某个系统的主要流程,可以通过事件风暴来探索。
如果业务非常复杂,仅仅通过事件风暴设计流程是不行的,必须借助流程框架才能解决。比如复杂电商系统有数十个甚至百多个业务场景(身份),不同业务场景有不同的流程和规则。
事件风暴关键概念
抽象记忆: 谁(actor), 看了什么(读模型Read Model),在聚合上干了什么(command),产生什么结果(event)
整体解释
-
Actor(用户/系统) 根据 Query Model(查询模型) 做出决策。
- 例如:用户(Actor)在电商网站(Query Model)看到“库存充足”,决定下单。
-
Actor 发送 Command(命令)到 Aggregate(聚合)。
- 例如:用户发送
PlaceOrderCommand到OrderAggregate。
- 例如:用户发送
-
Aggregate 处理 Command,生成 Domain Event(领域事件)。
- 例如:
OrderAggregate生成OrderPlacedEvent。
- 例如:
-
Domain Event 触发 Policy(策略),Policy 决定是否发送新的 Command。
- ✅ Policy 应作用于 Aggregate,而不是 External System。
1. 核心概念澄清 Business Rule VS Policy
| 概念 | 定义 | 执行时机 |
|---|---|---|
| Command | 表示一个意图(如 PlaceOrderCommand),由 Actor 发送给 Aggregate。 |
主动触发,通常是用户或系统发起的操作。 |
| Domain Event | 表示已发生的事实(如 OrderPlacedEvent),由 Aggregate 生成。 |
被动触发,是 Command 处理后的结果。 |
| Business Rule | 业务逻辑的约束条件(如“订单金额必须大于0”)。 | 可在 Command 或 Event 阶段执行。 |
| Policy | 对 Domain Event 的反应性规则(如“订单创建后自动预留库存”)。 | 必须由 Domain Event 触发。 |
- Domain Event 也可能更新 Query Model,供 Actor 后续使用。
- 例如:
OrderPlacedEvent更新“用户订单历史”查询模型。
- 例如:

1 事件(event):
领域事件(Domain Event)是一个非常关键的概念。
它代表了领域中发生的事实,领域事件强调的是业务过程中的某些关键动作或状态变化,这些变化对于业务流程和决策具有重要意义。
2 决策命令(command):
决策命令产生了事件,可理解为产生事件的动作,与事件一一对应。如用户已注册(User Registered)事件对应的决策命令就是注册用户(Register User)。
3 发起命令的参与者(who):发起命令的参与者User/Actor
发起命令的actor可以是 :人,外部系统External System和规则Policy,定时任务
前面的决策命令一定是由某个人或系统来发起的。比如:前面的注册用户这个命令,是由普通用户这个Actor发起的,进而可以联想到可能整个系统中还会有非普通用户,如管理员。
4 热点Hotspot(IDEAS, RISKS)
热点表示不确定的点、有风险的点或者需要特别注意的点,一般贴在事件旁边,代表这件事情值得特别关注。
热点使用紫色的便利贴表示,文字描述可以随意点,没有格式要求。
5 读模型Read Model
某个Actor做出决策Command的前提是需要看到某些信息,或者说,支撑Actor更容易做出决策命令Command的信息。读模型一般是通过Web页面(UI/UX)来展示更多的信息,以让用户更容易做出决策。
如何识别聚合
- 分析逻辑:
- 聚合是处理命令的最小单元,负责维护内部状态的一致性(不变性条件)。
- 例如,“订单已创建”事件由“订单”聚合处理,因为它需验证商品库存、用户权限等规则。
- 聚合的识别标志:
- 具有独立生命周期和全局唯一ID(如订单ID、客户ID)。
- 与关联对象(实体/值对象)有强一致性要求(如订单项需随订单一起创建或删除)。
划定聚合边界
- 原则:
- 高内聚:将紧密关联的实体和值对象组合到同一聚合(如“订单”聚合包含订单项、价格等)。
- 单一职责:一个聚合仅维护自身边界内的业务规则(如订单聚合不处理库存逻辑)。
- 引用方式:聚合之间仅通过聚合根ID关联(如订单聚合引用客户ID,而非直接操作客户对象)。
- 示例:
- 电商系统中,“订单”聚合根管理订单项(实体)和总价计算(值对象);“库存”聚合根管理库存扣减规则。
⚙️ 二、聚合的设计原则与实现要点
-
聚合的结构
- 聚合根:唯一入口,负责协调内部对象(如
Order类提供添加订单项、计算总价等方法)。 - 实体:具有局部ID(如订单项ID),生命周期由聚合根管理。
- 值对象:无ID,描述状态(如价格
Price),不可变。
- 聚合根:唯一入口,负责协调内部对象(如
-
一致性保障
- 规则:一次事务仅修改一个聚合的状态,跨聚合操作通过领域事件实现最终一致性(如“订单创建后发布
OrderPlacedEvent,触发库存更新)。 - 封装性:外部只能通过聚合根方法修改内部状态(如通过
Order.addItem()添加订单项,禁止直接操作OrderItem)。
- 规则:一次事务仅修改一个聚合的状态,跨聚合操作通过领域事件实现最终一致性(如“订单创建后发布
-
避免过大聚合
- 拆分依据:若聚合内对象过多(如超10个实体),或业务规则过于复杂,需拆分(如将“客户”与“订单”拆分为独立聚合)。

浙公网安备 33010602011771号