事件风暴与领域驱动设计(DDD)的实践思考

引言自2018年起,我开始接触领域驱动设计(DDD),并对其理论有了深刻的理解。尽管在战术层面有所实践,但战略层面的探索相对较少。事件风暴作为一种战略层面的业务探索工具,对产品和项目早期的业务梳理与沟通具有显著的促进作用,尤其适用于产品部门和一线业务部门。

事件风暴概述

官方定义事件风暴是一种协作工作坊,旨在探索复杂的业务领域。它具有多种应用场景,包括但不限于:

  1. 挖掘现有业务流程中的改进点2. 探索新业务模式的可行性3. 设计新的服务以实现各方利益最大化4. 创建支持快速发展业务的事件驱动型软件

核心理念事件风暴的本质是一套管理复杂软件系统多人协作的方法。它通过一系列活动规则,使得不同背景的项目干系人能够进行有效的沟通和协作。

事件风暴的实践意义

促进有效沟通事件风暴通过面对面的沟通和可视化的方式,帮助团队成员跨越信息孤岛,实现跨学科和跨部门的交流。

支持业务与技术融合事件风暴不仅关注技术实现,更重视业务需求的理解和表达,从而促进业务与技术的深度融合。

事件风暴的实施步骤

  1. 准备阶段:确定参与者,准备必要的工具和材料。2. 启动阶段:介绍事件风暴的目的和规则,激发参与者的兴趣。3. 探索阶段:通过讨论和协作,识别和定义业务事件。4. 分析阶段:深入分析事件之间的关系,构建业务流程图。5. 总结阶段:提炼关键发现,形成共识,并规划后续行动。

结语事件风暴作为一种战略实践工具,能够帮助团队在产品和项目的早期阶段进行有效的业务梳理和沟通。通过实践事件风暴,我们可以更好地理解业务需求,设计出更符合实际需求的软件系统。

参考链接- 事件风暴官方网站- Liam.wang:实践事件风暴Event Storming- Jeff Patton《用户故事地图》


在进行事件风暴(Event Storming)时,我们需要了解一些基础概念,以便更有效地进行讨论和达成共识。以下是对事件风暴中的关键概念的重新梳理:

事件风暴中的基础概念

事件(Event)

事件是业务领域中已经发生的、具有业务意义的事实。它们可能需要被记录或触发其他响应。

  • 定义:事件是系统受到的业务影响,例如,用户注册、邮件激活等。- 特点:与技术影响(如CPU负载或内存使用)相对,事件关注的是业务层面的变化。- 触发条件:通常,查询操作(如查看数据列表)不会产生事件,因为它们不涉及业务层面的变更。

表示方法

  • 使用正方形橘黄色的便利贴来表示事件。- 事件名称应使用过去时态,例如“用户已注册”(User Registered)或“激活邮件已发送”(Activation Email Sended)。

注意事项

  • 查询操作一般不触发事件。例如,点击查询按钮显示数据列表,通常不会有“数据已查询”或“列表已查询”的事件。 通过以上结构化的内容,我们可以更清晰地理解事件风暴中事件的概念,并在实际应用中更准确地识别和使用事件。

Domain Event

热点Hotspot(IDEAS, RISKS)

热点表示不确定的点、有风险的点或者需要特别注意的点,一般贴在事件旁边,代表这件事情值得特别关注。

热点使用紫色的便利贴表示,文字描述可以随意点,没有格式要求。


在事件风暴(Eventstorming)中,决策命令是一种重要的概念,它与事件紧密相关。决策命令是产生事件的动作,并且每个决策命令都与一个特定的事件一一对应。例如,如果有一个事件称为’用户已注册(User Registered)’,那么与之对应的决策命令就是’注册用户(Register User)’。 决策命令在视觉上用正方形的蓝色便利贴来表示。在实际应用中,你可以通过将事件的描述进行简单的反转来快速地识别出对应的决策命令。 以下是决策命令的要点概述:

  1. 决策命令与事件的对应关系:每个决策命令都与一个事件相对应,它们之间存在直接的因果关系。2. 表示方法:使用正方形的蓝色便利贴来表示决策命令。3. 实践应用:在进行事件风暴时,可以通过反转事件的描述来快速识别决策命令。 这种对应关系有助于团队成员在讨论和设计系统时,清晰地理解事件和决策命令之间的联系,从而更好地把握系统的动态和流程。

    在系统操作中,命令的发起者被称为参与者或Actor。例如,在进行用户注册这一操作时,命令是由普通用户发起的。这一概念可以扩展到系统中的其他角色,例如管理员,他们也可能发起不同的命令。 在进行Big-Picture Event Storming工作坊时,我们通常不会将决策命令直接展示出来。相反,我们使用小长方形的亮黄色便利贴来表示Command和Event,这样可以使整个工作流更加清晰和直观。 具体操作步骤如下:
  2. 确定命令的发起者,即Actor。2. 根据命令的性质,选择合适的便利贴颜色和形状。3. 将命令和事件以结构化的方式呈现在工作坊中,以便于理解和讨论。

    在领域驱动设计(Domain-Driven Design, DDD)中,事件(Event)的产生不总是由某个参与者(Actor)发出命令(Command)触发。有时,它们可能是由外部系统或规则自动触发命令的结果。以下是对外部系统和规则的描述,以及它们在DDD中的视觉表示方法:

外部系统(External System)外部系统在DDD中用大长方形的粉红色即时贴来表示。它们可以独立于系统内部的参与者,通过发送命令来影响系统的行为。

规则(Policy)规则在DDD中用大长方形的紫色即时贴表示。它们定义了系统必须遵守的约束和条件,可能会自动触发命令以确保系统的一致性和合规性。

在DDD的实践中,识别和表示这些外部系统和规则是至关重要的,因为它们是系统设计和行为的关键部分。通过使用即时贴,我们可以在工作坊或讨论中直观地展示和讨论这些元素。

视觉表示方法- 外部系统:使用粉红色的大长方形即时贴来表示。- 规则:使用紫色的大长方形即时贴来表示。

这种视觉表示方法有助于团队成员快速识别和理解系统设计中的不同元素,促进沟通和协作。

读模型(Read Model)概述

读模型是系统设计中的一个重要概念,它使得参与者(Actor)能够基于一定的信息做出决策。以下是对读模型的详细解析:

1. 读模型的定义读模型是支撑参与者做出决策的一组信息,通常通过用户界面(UI/UX)以网页形式展示。

2. 读模型的作用- 提供决策支持:读模型展示的信息帮助用户更容易地做出决策。- 增强用户体验:通过直观的展示方式,使用户能够快速获取所需信息。

3. 读模型的表示在系统设计中,读模型通常使用绿色正方形的即时贴来标识。

4. 读模型的应用场景- 决策制定:参与者在做出命令(Command)之前,需要查看读模型提供的信息。- 信息展示:通过Web页面展示更多信息,使用户能够更容易地做出决策。

5. 注意事项- 读模型的展示应具有条理性,确保信息的清晰和易于理解。- 读模型的设计应符合用户体验原则,以提高用户的决策效率。

6. 结构性示例假设一个电子商务平台的读模型,它可能包含以下结构:- 产品列表:展示可购买的商品。- 用户评价:提供其他用户对商品的评价信息。- 价格比较:显示不同供应商的价格,帮助用户做出购买决策。

7. 读模型与命令的关系读模型为命令的发出提供了必要的信息支持,是决策过程中不可或缺的一部分。

8. 读模型的优化- 定期更新:确保读模型中展示的信息是最新的。- 个性化定制:根据不同用户的偏好展示相关信息,提高决策的相关性。

9. 技术实现- 使用现代前端技术,如React或Vue,来构建响应式的读模型界面。- 后端服务应提供稳定且快速的数据接口,以支持读模型的数据需求。

10. 结论读模型是帮助用户做出更好决策的重要工具,它通过提供必要的信息和优化用户体验,提高了系统的交互性和效率。

聚合Aggregate的概念与应用

聚合(Aggregate)是领域驱动设计(Domain-Driven Design, DDD)中的一个核心概念,它代表了一组相关对象的集合,这些对象在业务操作中通常一起工作,并作为一个单一的数据修改单元。聚合通过定义清晰的边界,确保数据的一致性和完整性。

聚合的表示方法在事件风暴(EventStorming)中,聚合通常使用大长方形的黄色即时贴来表示。这种可视化的方法有助于团队成员快速识别和讨论聚合相关的业务逻辑。

聚合的业务流程1. 识别Actor:Actor是业务流程的发起者,可以是人或外部系统。2. Query Model/Information:Actor根据查询模型或信息做出决策。3. 执行Command/Action:基于决策,Actor对聚合或外部系统执行命令或动作。4. 产生Domain Event:命令的执行导致领域事件(Domain Event)的产生。5. 触发Policy:领域事件可能触发策略(Policy),这些策略可以是对聚合或外部系统的进一步命令或动作。6. Query Model/Information更新:领域事件的发生可能会更新查询模型或信息,为Actor提供新的操作依据。

聚合与领域事件的关联聚合中的操作通常与领域事件紧密相关。例如,当一个用户注册时,**用户已注册(User Registered)事件是由普通用户(Normal User)注册薄(Register)这个聚合上调用注册用户(Register User)**命令产生的。

聚合的业务意义聚合的设计有助于简化业务流程的理解和实现,它将相关的业务逻辑和数据封装在一起,使得开发和维护变得更加高效。

总结聚合作为DDD中的一个重要概念,通过在事件风暴中以黄色即时贴的形式表示,帮助团队成员理解业务流程,确保数据的一致性,并促进业务逻辑的高效实现。

事件风暴实践形式概述

事件风暴(Event Storming)是一种灵活的协作技术,它允许团队成员共同探索和理解业务领域。以下是两种主要的实践形式:

Big-Picture Event Storming

定义(What)Big-Picture Event Storming 是一种用于业务全景探索的事件风暴形式。

参与者(Who)- 产品经理或开发Leader/架构师作为主持人- 市场分析员、业务人员、财务、UX等相关部门代表- 总人数控制在8-12人

时机(When)在项目或产品立项之后,业务人员(产品人员)已经对项目/产品有了基本构思时进行。

目的(Why)- 与所有利益相关者(Stakeholders)共同探索业务全景- 搭建平台,让Stakeholders贡献专业知识- 确保团队成员了解全景/边界、风险点- 明确各自在项目中的职责- 发现产品/项目的逻辑漏洞

注意事项- 确保所有关键角色的参与,以获得全面的视角- 保持沟通的开放性,鼓励团队成员提出问题和想法- 利用视觉工具,如白板或大屏幕,以促进信息共享和讨论

结构化内容1. 项目/产品构思阶段:当业务人员对项目/产品有了初步想法时,是开始Big-Picture Event Storming的最佳时机。2. 团队组建:选择具有不同背景和专业知识的团队成员,确保多元化的视角。3. 全景探索:通过事件风暴,识别和讨论关键业务事件、命令、聚合、限界上下文等元素。4. 风险识别:在讨论过程中,识别可能的风险点和潜在问题。5. 职责明确:明确每个团队成员在项目中的角色和责任。6. 逻辑漏洞发现:通过集体智慧,找出产品/项目设计中的逻辑漏洞。

总结Big-Picture Event Storming 是一种有效的团队协作工具,它帮助团队成员共同构建对业务领域的深入理解,为项目的成功奠定基础。

设计层面的事件风暴(Design-Level Event Storming)

定义与参与者- 定义:一种专注于软件设计细节的事件风暴形式。- 参与者:开发领导者/架构师主持,业务人员/产品经理以及研发团队的其它成员,包括测试、前端/后端、UI等。团队规模建议控制在6-12人,以减少沟通成本。

时机- 在完成宏观事件风暴(Big-Pic EventStorming)之后,产品经理或业务人员进一步梳理业务,或在研发团队介入特定业务上下文之前。

目的- 让研发团队全面了解业务全景,学习业务知识,为研发工作做准备。- 通过业务建模和统一业务语言,明确业务优先级。- 产品经理/业务人员补充实现细节,调整用户故事和优先级。

两种事件风暴形式的区别

人员差异- 宏观事件风暴:侧重于业务方,包括所有干系人,研发领导者或架构师参与。- 设计层面事件风暴:侧重于研发团队,包括研发领导者或架构师。

目的差异- 宏观事件风暴:探索业务全景,发现关键点,补充跨领域知识,让干系人了解项目全貌和自身职责。- 设计层面事件风暴:向研发团队传播业务知识,作为研发与业务沟通的桥梁。

范围差异- 宏观事件风暴:关注整个业务全景。- 设计层面事件风暴:关注全景中的特定业务上下文。

研发组织中的问题

沟通障碍几乎所有研发组织都面临类似的沟通问题,尽管每个组织都强调自己的独特性。

“部门墙”(Organizational Silos)- 部门墙可能来自公司行政划分,也可能是虚拟组织或团队。- 部门墙是职责划分的具体体现,有助于快速界定工作边界,但同时也增加了跨部门协作的沟通成本。

影响- 干系人如果不了解全貌,可能倾向于拖延而非积极行动。- 难以在跨部门间达成共识,共识可能主观且错误,导致误解和隐形斗争。- 企业架构混乱。架构师如果不了解全貌,将难以做出良好决策,长期割裂会导致企业架构混乱。

注意- 以上内容为重新编写的事件风暴介绍和研发组织问题的分析,旨在提供结构化和条理化的输出。

自组织团队与决策的重要性

在企业中,团队的自组织能力对于系统理解与决策至关重要。一个团队若不能理解整个系统,就无法实现真正的自组织。同时,决策过程的透明度和去中心化也是团队自组织的关键。以下是一些影响团队自组织能力的因素:

  1. 高层集中式决策:当决策由高层集中制定并突然公布时,团队成员可能感到被动和缺乏参与感。2. 与利益相关者单独沟通:如果决策过程中只与部分利益相关者沟通,而忽视了其他成员,这同样会阻碍团队的自组织。

技术人员与业务人员的沟通障碍

技术人员在与业务人员沟通时,可能会不自觉地表现出对自己专业能力的自豪感,有时甚至会出现轻视业务人员的情况。这种现象可能导致沟通障碍,因为技术人员可能过于专注于展示自己的专业技能,而忽略了真正解决业务问题的重要性。

换个角度看企业软件研发

软件研发是一个学习过程

工程师在面对新的业务领域时,需要投入大量时间进行学习。这个过程往往不是他们所擅长的技术领域,而是需要深入了解业务知识。然而,业务学习常常被忽视,甚至被某些工程师所不屑。这种忽视可能导致资源浪费,因为工程师可能在没有清晰需求的情况下就开始编写代码。

业务学习的重要性

业务学习是软件研发中不可或缺的一部分,它可以帮助工程师更好地理解需求,从而设计出更符合业务目标的解决方案。有效的业务学习可以通过业务建模来进行,这不仅能够激发工程师的探索欲和成就感,还能帮助他们解决更广泛的问题。

软件研发不只是写代码

软件研发是一个全面的过程,包括设计、编码、测试、部署和维护等多个阶段。不同角色对软件研发的理解可能有所不同,但重要的是让所有相关人员都了解整个研发流程,认识到除了编码之外,还有许多其他重要的工作要做。

维护和需求调整的成本

在企业软件的整个生命周期中,维护和需求调整的成本往往占据了很大一部分。如果前期需求不明确,将大大增加后期的调整成本,从而影响整体的项目成本。因此,确保需求与所有干系人对齐是至关重要的。

结论

通过上述分析,我们可以看到,自组织团队的构建、技术人员与业务人员的沟通、以及对软件研发全过程的理解,都是企业软件研发成功的关键因素。

图片来自百度百科

写代码以及上线的过程,本身是软件研发比较确定的一部分,所以这部分的提效相对容易。有很多实践来提高写代码过程的效率,比如代码的最佳实践、封装好的类库/接口/服务,招聘更有经验的工程师等。也可以通过DevOps的自动化与规范提高Code -> Build -> Deploy -> Running 这个过程的效率。

> 软件研发就是等待

这是工程师的小秘密,也是合理摸鱼的最佳实践。等待Build完成、等待UT跑完、等待业务把需求明确、等待别人主动讨论问题、等待申请审批通过、等待Leader布置任务等等,更难以注意到的是,在等一件重要的事情的时候,去做无关紧要的事情,让自己忙起来。 可以通过简化流程和尽可能的自动化来减少等待,但不能完全消除(也没有必要,合理的“等待”并不会降低效率)。

> 软件研发就是做决策

业务需求的明确的过程是一个决策的过程,架构师做设计方案的过程是一个决策的过程,制定具体实现方案,技术选型的过程是一个决策的过程,类和方法以及变量的命名也是一个决策过程。基本上一个企业软件的诞生就是一群人做了很多决策的结果。决策的质量决定了企业软件的生命力,足够的输入和讨论决定了决策的质量。与干系人相关却没有达成一致的决策是无效的决策。

事件风暴能解决的问题

正如本文“实践形式”中描述的那样,事件风暴主要有两种形式用于解决不同的问题。总结来看,它打破了“部门墙”,能让所有人了解到业务的全貌,能让技术和业务在同一个游戏平台上解决真正的问题,能让所有人快速学习业务知识。

  • 当软件系统需要进行跨部门的协作与对齐时,能帮助所有stakeholder看到整个系统的全貌、让技术和业务在同一个问题上进行讨论、发现有价值的问题、定义与明确各stakeholder的职责、发现逻辑漏洞、划分系统上下文、统一语言。
  • 当软件系统开始研发之前,能帮助研发团队所有人看到系统的全貌或者一个上下文的全貌、协助进行业务建模,统一语言、非常适合项目研发的kickoff。
  • 当有新人入职时,能帮助新人快速的学习系统的全貌、边界以及统一的语言。

事件风暴不能解决所有问题

软件研发中从来没有所谓的银弹。

不能解决所有的沟通协作问题

不同的沟通形式和方法用于解决不同的问题,事件风暴不可能解决所有沟通问题。如Scrum的站会用于快速同步项目进度、困难,梳理会用于梳理用户故事、评估工作量、同步项目milestone等,回顾会用于团队反思改进、分享最佳实践、表扬激励等。

不能解决Why的问题,更适合解决How的问题

一件事做与不做,取决于长期或者短期带来的价值。如对于企业中产品研发来说,一个产品的做与不做,取决于前期的市场调研与分析,有很多工具和方法论用于解决这个问题,比如SWOT、5 Force analysis、BRD,AWS的逆向工作法等。事件风暴并不能解决“为什么做”的问题,更适合解决“怎么做”的问题。

不适合用做底层技术的讨论

实践证明,事件风暴并不适用于存储系统、API网关、网络通信等底层技术或基础设施的讨论。这些更多需要专业的技术能力,且落地的时候有标准或者最佳实践可以遵循。一般的做法是,架构师或者技术专家进行这些系统的设计,然后跟技术团队沟通并实施,沟通的更多是关于技术人员容易理解的技术上的问题,而不是业务知识。

其他思考

事件特殊在哪里?

  • 普适:事件流以其陈述性且理解使用门槛较低的特点,非常适合不同背景的人通过其进行沟通
  • 准确:事件是已经发生过的、确定的事情且单个定义清楚的事件包含的信息有限,能有效降低对系统描述的歧

软件系统是对现实世界中某些问题的解决方案的实现,所以软件系统表示的是解决方案本身,而不是问题本身。要想解决现实世界中的某些问题,首先要明确问题本身,然后再明确解决方案,最后才是如果实现这个解决方案。

用事件的视角看,问题的解决方案就是一系列的事件按照时间顺序发生,然后问题就得到了解决。对于软件系统,也是如此,可以认为软件系统就是由于某些刺激,而发生了一系列的事件,每一个事件发生后,系统的状态就与事件发生之前不一样了,而软件系统解决问题的目标正是通过不断的响应刺激,产生事件,改变自身状态来达到的。

问题的解决方案(业务)和对解决方案的实现(技术)可以通过事件串起来,他们对事件的理解应该是一致的,否则无法解决问题。

事件风暴与架构活动

架构活动的关键在于定义形式结构与功能(‘形式’和‘功能’的定义来自于《系统架构:复杂系统的产品设计与开发》),而EventStroming是一个通过协作式思考系统中的功能(Event由功能产生),从功能反推系统形式结构的一个活动。

架构活动应该尽可能早的确定所有干系人,识别问题并控制风险,尽可能的消除歧义,确保解决方案能产生真正价值。可以说,EventStorming活动是架构师进行架构活动的辅助工具,同时也提供了独特的视角来确定利益相关者和受益者,需求收集与目标定义,以功能为切入点进行概念的抽象与系统边界的划分,并建立共识。

事件协作式架构活动

事件风暴与领域驱动设计(DDD)的关系

映射关系- Big-Picture 事件风暴:对应战略设计中的领域分析,用于划分领域边界和限界上下文。- Design-Level 事件风暴:细化领域分析,与DDD的战术设计联系,识别聚合根和实体。

统一语言统一语言是DDD和事件风暴的共同点,贯穿整个业务建模过程。

核心区别DDD关注业务领域,是一套应对复杂业务系统研发的方法论;事件风暴是探索业务领域的一种方式或工具。

事件风暴与头脑风暴的比较

目的和产出- 头脑风暴:创意碰撞,产出点子。- 事件风暴:业务建模,产出业务系统模型。

范围- 头脑风暴:适用范围广泛。- 事件风暴:专门面向业务软件研发。

事件风暴在技术企业中的落地要求

企业氛围- 开放:接受新方法论和观点。- 协作:共同完成工作。- 务实:脚踏实地完成任务。- 狼性:有活力,能投入精力。

架构能力- 需要有架构师岗位,作为事件风暴的主持人和发起者。

参考资料- 《Introducing EventStorming》 - Alberto Brandolini- Awesome EventStorming- DDD:EventStorming(事件风暴) - ShouKai Blog- 《系统架构:复杂系统的产品设计与开发》 - Edward Crawley/Bruce Cameron/Daniel Selva