事件风暴工作坊

背景
什么是事件风暴
事件风暴是一种以协作探索复杂业务领域为目标的,灵活的工作坊(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)

整体解释

  1. Actor(用户/系统) 根据 Query Model(查询模型) 做出决策。

    • 例如:用户(Actor)在电商网站(Query Model)看到“库存充足”,决定下单。
  2. Actor 发送 Command(命令)到 Aggregate(聚合)

    • 例如:用户发送 PlaceOrderCommandOrderAggregate
  3. Aggregate 处理 Command,生成 Domain Event(领域事件)

    • 例如:OrderAggregate 生成 OrderPlacedEvent
  4. 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 触发
  1. 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,而非直接操作客户对象)。
    • 示例
      • 电商系统中,“订单”聚合根管理订单项(实体)和总价计算(值对象);“库存”聚合根管理库存扣减规则。

⚙️ 二、聚合的设计原则与实现要点

  1. 聚合的结构

    • 聚合根:唯一入口,负责协调内部对象(如Order类提供添加订单项、计算总价等方法)。
    • 实体:具有局部ID(如订单项ID),生命周期由聚合根管理。
    • 值对象:无ID,描述状态(如价格Price),不可变。
  2. 一致性保障

    • 规则:一次事务仅修改一个聚合的状态,跨聚合操作通过领域事件实现最终一致性(如“订单创建后发布OrderPlacedEvent,触发库存更新)。
    • 封装性:外部只能通过聚合根方法修改内部状态(如通过Order.addItem()添加订单项,禁止直接操作OrderItem)。
  3. 避免过大聚合

    • 拆分依据:若聚合内对象过多(如超10个实体),或业务规则过于复杂,需拆分(如将“客户”与“订单”拆分为独立聚合)。

参考资料

https://zhuanlan.zhihu.com/p/399103071

posted @ 2025-03-28 13:25  向着朝阳  阅读(70)  评论(0)    收藏  举报