简介: 在考虑如何对业务模型进行抽象从而建立领域模型之前,必须解决业务与产品、开发之间“沟通”的问题。如何让业务人员和开发人员顺畅沟通,在业务流程设计中不遗漏成败攸关的业务场景?如何才能让业务沟通的过程顺畅过渡到架构设计、编码乃至测试?阿里巴巴技术专家李建结合团队的实际案例,分享了他们在使用 Event Storming(事件风暴)进行领域建模时的经验、收获和思考。
一 软件研发的困境
“失效”的语言交流
日常研发过程中不同角色经常需要进行各种交流:沟通业务需求、讨论产品原型、讨论设计方案等。每个环节不同角色反复沟通,这是研发过程非常重要的环节。但问题是:我们花费大量时间沟通,真的“说”清楚了吗?
让我们看两个例子:
上面的两段对话发生在一次项目 Review 的过程中。通过第一个对话,我们能看出不同的角色在沟通的时候遇到了障碍;通过第二个对话说明即便是相同的角色,沟通在某种程度也遇到了障碍。
软件研发的困境
无论传统的瀑布流程还是敏捷模式,软件研发总体上能划分成几个阶段:提出需求,产品设计,研发,测试,最后上线。不同阶段会产出不同交付物,有些比较简单,也有些比较详尽:MRD,PRD,技术方案,验收方案等。在整个过程中,我们还会组织不同会议,或者是线下讨论。
大家想一想,在哪一个阶段暴露了最多的问题?
不管我们多么期望在早期发现问题,然而现实是越到研发晚期越会暴露更多问题。当产品进入测试阶段,当上线后真实数据开始跑起来,当业务同学开始使用产品,这时候问题会像泉水一样主动涌现出来,用户会反馈各种问题:“这个不是我想要的功能”,“XX 和我的预期不一样”等等。通常在软件研发的后期发现很多这种类似的问题。软件研发发展到今天,这个问题依然没有被很好的解决。
阻碍产品正确交付的原因
我们通过下面一个例子来分析什么原因阻碍了产品的正确交付。
当产品同学提出需求的时候,研发同学做了好的回应,但实际上双方想的内容并不一致,这种情况我们称之为表面一致;当产品上线后,产品同学提出需求疑问时,研发同学的回答充满了各种技术行话:定时系统,原子性等。显然大部分产品同学不能理解这些技术行话,对话进入停滞状态,我们称这种现象为沟通障碍。在软件研发中该问题反复的出现:沟通不畅阻碍了产品价值的正确交付。在不同角色进行交流时,三个原因阻碍了沟通的顺畅进行:
- 得到的信息不同:产品同学和业务同学关注的是业务需求,市场情况,近中远期规划,以及运营数据等;开发同学关注的是一个个具体的需求列表,功能点,是实现层次的细节信息。
- 思维方式不同:产品同学关注业务 / 需求的合理性,产品逻辑,用户体验;而开发同学关注方案的可行性,实施成本,系统稳定性等。
- 沟通语言不同:产品同学用描述性的语言,语言的模糊会导致不同角色理解的不同;而开发同学习惯使用技术语言,SDK、数据库、一致性等。不同角色交流的时候,会因为语言不相容,沟通不到一起去。
由于以上的原因,沟通容易陷入“鸡同鸭讲”的窘境:讨论很热烈,甚至能取得表面的一致,实际并没有“说”清楚。
洞察软件研发困境
Event Storming 方法的发明者 Alberto Brandolini 认为:产品体现了程序员对业务的理解(或误解)。很多时候沟通失败导致的误解进入产品实现。于是真正的业务需求在产品中没有得到体现。沟通失败是软件研发的一个痛点,有待解决。
二 Event Storming
Event Storming 介绍
Event Storming(ES):由不同角色共同参与,用彩色贴纸进行交流的工作坊。
如上图,一群同学围绕一个业务场景,用贴纸进行交流,这就是 ES 工作坊。通过贴纸进行交流,让大家用同一种沟通语言,同一个思维方式,让大家的思维在一个频道上,这是 ES 的形式,也是 ES 的目的。
Event Storming 语法
ES 定义了一套彩色贴纸的“语法”:不同颜色的贴纸都有定义。浅黄色代表 Actor (角色)、蓝色表示 Command (命令)、粉色代表 Policy (业务规则)、浅粉色代表 System(系统)、橙色代表 Event (事件),浅绿色表示 Read Model (读模型)、红色代表 HotSpot (热点 / 问题)。
用 ES 的语法表达用户的下单流程:买家 (浅黄色贴纸) 提交订单(蓝色贴纸),如果订单里商品是在线状态,购买量小于商品库存量 (粉色贴纸 Policy),那么订单创建成功(橙色事件贴纸),已创建的订单 (绿色贴纸) 展示给用户。订单创建后需要通知买家(业务规则,粉色贴纸),系统执行发送站内信(蓝色贴纸)。
二 如何在业务中使用 ES
下面我们通过一个业务场景(优惠券的投放和使用)介绍如何使用 ES。
业务背景介绍
电商网站提供各种优惠券:满减券,折扣券,有无门槛券。
下图描述电商运营小二在活动中投放优惠券的整体流程:小二先创建优惠券,然后再创建一个活动,把优惠券和活动关联起来。活动通过公司财务的审批后才可发布上线。消费者在活动页面领取优惠券,在下单流程使用优惠券抵消金额。最后活动结束时要对整体活动的数据进行统计分析。
准备 Event Storming
在开始 ES 前,先做好准备:
- 准备物料:彩色贴纸、笔纸、一个足够大的房间等。房间里不要有椅子,因为在 ES 过程中,我们希望大家都全神贯注的投入,而不是坐在椅子上开始放松。
- 邀请正确的人:有问题的人和有答案的人。程序员、交互设计师、测试等都是有问题的人,需要通过 ES 理解业务和产品;有答案的人通常是用户、业务或产品,他们通常能回答业务的背景,诉求和目标。
Event Storming 的过程
ES 可以分为开场介绍、ES 沟通业务和讲故事三个阶段。
开场介绍
在 ES 中有一个特殊的角色叫做 Facilitator(推动者),一般是 ES 的组织者。在 ES 开始前,Facilitator 向大家介绍 ES 是什么,有什么好处,以及彩色贴纸的用法。然后介绍讨论的范围和目标。
比如,今天讨论优惠券场景,目标是理清营销活动过程中优惠券的业务流程。最后 Facilitator 强调 ES 的规则:所有的讨论都写在贴纸上;不允许使用电脑,手机;也不允许坐下。在 ES 的后续过程中,Facilitator 还需要承担另外两个重要职责:保持参与者的专注,通过提问驱动交流。
ES 的方式沟通业务
第一步先梳理事件(橙色贴纸): 事件是已发生且重要的事情。事件必须是既成事实,且业务关注的事情。通常 Facilitator 会先准备第一个事件(可以是系统中任一事件),然后把它贴到墙上。
假设第一个事件是:优惠券已领取。接下来 Facilitator 通过提问引导大家找到更多的事件:
- 事件发生前有哪些事件(“优惠券已领取”前须先有“活动已发布”事件)?
- 事件发生后下一个事件是什么(“优惠券已领取”后有“优惠券已使用”,“优惠券已过期”等事件)?
提问会引导参与 ES 的同学将新发现的事件不断补充到墙上。事件要保持整体的时间顺序:先发生的事情贴在左边,后发生的事情在右边。通常大家容易关注系统的正常流程,也就是 Happy path。这时候 Facilitator 需要引导大家关注业务的非正常流程 Unhappy path。边界条件,异常情况通常是业务复杂性的重要原因,也是非常容易被忽视的部分。
- 事件一定会发生吗(优惠券一定领取成功吗?不是,贴上“优惠券领取失败”事件)?
追问 unhappy path 梳理出业务的完整视图,当大家发现新事件的速度接近停滞的时候,就应进入梳理业务规则的阶段了。
Policy,业务逻辑或规则,这是业务中最重要的部分。Facilitator 会提出以下问题:
- 事件是否一定成功?如果不是,那么成功的前提条件是什么?
- 该事件是否会导致其他事件的发生(Reaction)?
例如“活动已提交”事件:
- 活动提交成功的前提条件:活动已关联有效优惠券,且已选择了生效方式,并且选择了适用人群。
- 活动提交后,会导致审核任务已创建事件,这里的业务规则是:活动提交或需创建审核任务。
接下来找出三个角色:Actor (和系统交互的人),Command (用户动作) 和 Read Model (辅助用户决策的工具)。Facilitator 提出以下问题:
- 是什么触发了事件?即事件发生的原因 (ES 的语法:when Event,then Command)。
- 谁执行了动作。是人,系统,还是时间(例如定时触发的事件)?
- 做出动作前,用户需要获取哪些信息?
以上的问题会引导大家找到 Actor, command 和 Read Model。在营销活动已提交事件中:小二(Actor)执行了提交活动(Command), 从而产生了“活动已提交”事件。
最后介绍 Hotspot:业务痛点、瓶颈、模糊点。Hotspot 是 ES 过程中随时都应该发现并记录下来的。Facilitator 可以引导大家发现业务中未描叙到的问题,例如:用户使用优惠券进行支付的场景中,如果用户支付失败,已使用的优惠券该如何处理呢?优惠券应该返还给用户,还是不做处理?通过提出这样的问题,引导大家对业务流程进行更深入的讨论。通常在 ES 的过程中,识别并记录 Hotspot,不要在 ES 中尝试解决所有的 hotspot。
以上介绍了 ES 的主要元素:Event,Policy,Actor,Command,Read Model,Hotspot。用 ES 描述了优惠券发放的业务流程,最后一步是“讲故事”(storytelling) 的阶段。
讲故事
Facilitator 邀请不同的人担任志愿者,每个志愿者讲一段故事:按时间顺序和 ES 描叙的逻辑,向其他人介绍业务流程。过程中,听众注意到不一致的地方随时提出问题,大家讨论问题,通过增加 / 删除 / 移动贴纸来修复问题,并继续讲故事的流程。
最开始大家会按时间正序讲故事,最后大家还可以倒序讲故事。梳理业务的异常场景,倒序讲故事的方法更有效。例如为什么会发生“优惠券领取失败”事件,事件的原因是 balabala…
经过讲故事阶段的完善,大家获得了业务的完整理解,这时候可以结束讨论,保存相关材料,遗留下来的 Hotspot 交由相关同学跟进。
Event Storming 常见问题
ES 比其他方式更能帮助大家顺畅的沟通,但是对于首次参与或组织 ES 的同学也有一些疑问。以下列出一些常见问题:
Q:ES 通常邀请多少人参加?我需要邀请所有角色吗?
A:不一定。ES 鼓励不同角色共同参与,但是参与人的态度更重要,积极主动参与是 ES 成功的关键。通常一个 Pizza (8 – 10 人) 的规模,是适合 ES 人数。
Q:我的业务场景和复杂,在 ES 中要梳理完整个业务流程吗?
A: 不需要。ES 需要大家高度参与,因此需要控制好时间。每次 ES 的范围选择复杂业务场景的一部分,保证 ES 的效果。
Q:我应该在什么阶段做 ES?
A:项目的任何阶段都可以做 ES。ES 既可用于梳理业务现状,也可以用于设计业务的未来方案。
Event Storming 小结
下面的四个图直观的解释了 ES 的作用:
- 图 1,说明不同角色通过语言交流,虽然达成表面一致,实际上大家理解不一致。
- 图 2,ES 要求大家通过贴纸的形式可视化出来脑海中的想法,从而使分歧自动显现。
- 图 3,ES 通过不断的提问触发讨论,从而能够拉通认知,消除分歧点和模糊点。
- 图 4,ES 拉通了大家对业务的理解,从而达成了真正的共识。
总的来说,ES 让不同的角色用同一种语言(彩色贴纸)从全局对业务达成共识。
四 从 ES 到代码
简单介绍下 ES 如何顺畅过渡到 DDD(Domain-Driven Design 领域驱动设计)。
提取业务概念
DDD 中最重要的是统一语言:交流使用统一语言;模型表达统一语言;代码表达统一语言。语言是由概念组成的,ES 的过程已经将概念写在贴纸上,并且在交流中反复使用。例如:优惠券,营销活动,已领取优惠券,领取方式,人群等。
一部分概念有生命周期,并且有唯一的标识符。例如:营销活动,优惠券,已领取优惠券。这些就是 DDD 中的实体;还有一部分概念标识一个完整的业务含义,但是没有生命周期,并且属性相同的两个对象可以替换,这些对象就是 DDD 中的值对象,例如:领取方式,生效方式,人群。
提炼模型
概念和概念之间是有关系的。比如说,优惠券和营销活动有关联关系,已领取优惠券是在某个营销活动下领取的,营销活动也包含很多信息,它的生效方式是什么,领取方式是什么,人群是谁。概念与概念之间的关系也就是领域模型。
从模型到实现
将 ES 贴纸重新组合:围绕一个核心概念,将与该概念有关的 Event,Command,Policy 组合在一起。例如下图左边围绕营销活动为中心重新组织了贴纸(Command,Policy,Event),这些贴纸和右边的代码映射起来,这也就是 DDD 中说的代码表达统一语言。到此,简单介绍了如何从 ES 到概念,从概念到模型,以及模型和代码实现是怎么关联起来的。
架构,代码和约束
下图简单描述应用架构,代码结构,以及如何通过 ArchUnit 实现架构约束。
四 总结
ES 的价值在于:不同角色在具体业务场景下用一种共同语言(彩色贴纸)进行交流,通过不断提问触发探索、讨论,最终达成真正共识。
阿里巴巴研发效能峰会 | 架构设计与代码智能专场
6 月 13 日,阿里巴巴研发效能峰会架构设计与代码智能专场将围绕领域驱动设计、代码可测试性、代码智能、代码数据打标等技术,探讨如何从架构设计和机器智能方面让代码更加容易被编写和维护。
点击”阅读原文“立即参与!