你好,我是钟敬。
上一讲,我们正式开始了第一个迭代,并简单分析了迭代一的需求。今天,咱们就要根据DDD的基本开发流程,使用事件风暴方法来进一步梳理需求。
你可能会问,上一讲的需求好像已经说得挺清楚了,为什么还要用专门的方法来梳理呢?
其实,在真实项目,尤其是敏捷项目里,领域专家很可能不会像我们上一讲那样,一开始就把需求都一一列出来,需求可能仅仅停留在领域专家的脑子里。所以,我们就需要一种方法,能够将这些头脑中的需求挖掘出来。
而且,即便领域专家已经把需求写出来,我们也很难保证没有遗漏,保证开发人员都彻底理解了。而事件风暴不仅能帮助我们尽量把需求补充完全,而且还能以协作的方式保证业务人员和技术人员对需求理解一致。
此外,事件风暴方法也能够帮助我们识别领域对象,这也是我们进行领域建模前的重要一步。尽管对于建模高手来说,通过“聊天”的方式就能把模型画出来,但对于多数开发团队而言,还是需要一种套路化的方法作为辅助,一步一步地做。
这节课我们从实践入手,让你真正掌握事件风暴的概念和具体操作。
事件风暴是怎么一回事?
那么,事件风暴是怎么来的呢?
一般来说,为了理解需求,我们首先要分析系统具有哪些功能,这些功能由什么人操作,会产生什么效果。这个过程传统上叫做“捕获行为需求”。
捕获行为需求的方法有好几种,在传统的软件工程中,最常用的方法是“用例”,也就是Use Case。但是,Eric Evans在《领域驱动设计》这本书里,并没有规定捕获行为需求的具体方法。直到2013年,一位叫Alberto的DDD专家提出了“事件风暴”,也就是Event Storming。
这种方法简单易学,而且充分体现了DDD中沟通协作、统一语言等要点,所以逐渐开始流行起来。你可以先看看这张图,这里说明了事件风暴的主要过程:

这里的第一步是识别领域事件,在这一步,我们要找到业务流程中发生了哪些事情;第二步是识别命令,进一步说明是什么角色,做了什么操作,导致上述事情的发生;而第三步是识别领域名词,从领域事件和命令中找到名词性概念,为进一步的领域建模打下基础。这里每一步的具体做法和要点,我们后面都会详细介绍。
那么现在,咱们就来想象一下如何在真实的项目中一起做事件风暴。为了保证把细节讲清楚,我们会分为两节课进行,今天的课先聚焦于第一步,识别领域事件。
我再强调一句,由于事件风暴是一个动态的协作过程,不太容易通过文字表达,所以在看后面内容的时候,你一定要充分发挥想象力,让头脑中有“画面感”,脑补出咱们两个人唇枪舌剑,反复讨论的过程。
事件风暴的准备
不过,在正式开始事件风暴之前,我们还要先做一些准备工作。
首先是人员的准备。事件风暴要求业务和技术人员共同协作。业务人员,也就是之前说过的“领域专家”,在实践中一般由业务部门的专家,或者产品经理、PO(Product Owner)、BA(Business Analyst)等角色来担任。技术人员呢,首先要有架构师,其次也可以有技术经理,或者其他的开发人员、测试人员也可以参加。
第二是场地准备。我们需要找一个比较大的会议室,或者至少有一面足够长的墙。
最后是器材准备。我们需要几套彩色的便利贴,到时候我们会把事件风暴的主要内容写在上面。另外,通常还要一卷一开的大白纸,把这些白纸打横,一字排开,贴在会议室的墙上,用来贴便利贴。
事件风暴的第一步:识别领域事件
好,现在还是我来扮演产品经理,你来扮演架构师。而且假设我以前做过事件风暴,而你是第一次,所以我比你知道得多一点。
一开始,我先口头给你讲了一遍需求,你大概听懂了。然后我们就开始事件风暴的第一步:识别领域事件。
所谓领域事件,就是在业务过程中,业务人员要关注的那些已经发生的事儿。比方说,对于电子商务系统,订单已提交、商品已签收等等,都是领域事件。实际上,领域事件表示的是,业务流程中每个步骤引发的结果。事件风暴的作者认为,从结果入手来梳理需求,比从操作入手,更容易把业务想清楚。事件风暴中的“事件”两个字就来源于领域事件。
另外,咱们还要注意领域事件的命名,如果套用英语的语法来说,一般是完成时 + 被动语态。比如说,订单已提交,这个“已”字就是完成时,代表已经发生的事情。而订单已提交也可以说成订单已“被”提交,实际是被动语态,只不过一般把被字给省掉了。
识别“项目管理”流程的领域事件
接下来咱们一个一个业务流程来做。至于具体先做哪个流程,并没有特别的规定。不过由于项目管理这个流程比较长,我们就拿这个流程为例来讲吧。
首先,咱们花十来分钟时间,各自按照自己的理解,把项目管理中发生的各个领域事件,分别写在橙色便利贴上。然后按大致的时间顺序贴在墙上。每人贴一行。写出来以后大概是下面这个样子:

然后,就可以对比咱们两个人写得有什么不一样,再经过讨论得出一致的结果。现在,咱们从左到右看一下。
第一步就发现了一个小区别。你写的是“客户已创建”,我写的是“客户已添加”。

那么你就会问我:“业务人员一般会说客户已创建还是客户已添加呢?”
我告诉你:“一般是说客户已添加,因为从业务的角度,客户本来就是存在的 ,不需要创建,只是把客户资料添加到我们的系统而已”。你表示同意。
然后我又叮嘱了一下:“以后添加客户的时候,都说添加这个词,别再说创建了。”这时候,其实我们已经是在建立“统一语言”了。统一后的结果是下面这个样子:

第二步,你写的是“签订合同”,我写的是“合同已签订”。

一说你马上就反应过来了,刚才我们说过要用完成时和被动语态,“签订合同”是个动作,不是事件。所以达成一致后,结果变成下面这样:

下一步,你写的是“项目已创建”,我写的是“合同已生效”。不过我后面还有一步“立项”,应该和你的“项目已创建”是一回事,所以说明我比你多了一步“合同已生效”。

于是你又问了:“合同签订以后不是马上就生效了吗,还要有一个额外的生效步骤吗?”
我解释说:“合同签订的时候未必马上生效,比如1月1日签了合同,但合同中可以约定,真正生效是在2月1日,所以需要一个单独的步骤让合同生效。”这时候,你知道了一条原来不知道的领域知识。
然后你又问了:“我写了项目已创建,但是你写的是已立项,你这种写法好像和其他的不太一致呀。”
我解释说:“虽然我们为领域事件命名的时候,常常用‘什么什么已什么什么’的形式,不过如果业务上已经有约定俗成的术语,我们就直接使用术语,这样更容易和业务沟通。现在业务觉得已立项是一个通用的术语,写成项目已创建反而显得生硬。”
现在你又知道了,在DDD中的各种命名,一般都优先使用约定俗成的业务术语。统一后的样子如下图:

再来看后面三步,这时我发现自己漏写了“项目已启动”。然后我们再比较了一下“项目已终止”和“项目已结束”两个说法,觉得“项目已结束”更符合业务术语。而“合同已结束”这一步,咱们俩是一样的。

不过我在“项目已结束”前面还多了一个“员工已分配”。

于是你又问我:“刚才你讲需求的时候,好像是把员工分配作为一块单独的需求来讲的,不属于项目管理这个流程吧?”
我想了想,说:“员工分配背后的业务逻辑有点复杂,所以之前单独拿出来讲,其实员工分配是项目运作中的一个重要环节,放在项目管理中也没毛病。”你对此表示认可。
这时我又补充了一点:“员工分配到项目的时候,要填入预计的投入工作量的百分比,一个人可以同时上多个项目,但预计的投入百分比总和不能超过100%。这种逻辑一般叫业务规则,为了避免忘记,咱们也写在便利贴上吧。”
于是我们把业务规则写在浅灰色便利贴上,贴在“员工已分配”事件的下方。经过这几步,结果变成了下面这个样子:

再下一步,你多了一个“客户已终止”。

我解释说:“客户可以在系统中长期存在,以便不断挖掘商机,一般不必专门进行终止。理论上说,万一客户破产了,是应该终止,不过目前业务上还没有这个需求,这一点可以以后再考虑。”于是我们把“客户已终止”拿掉了。
然后你又发现,我的流程中最后还多了一个“客户经理已更换”。

你有点惊讶地问:“可以更换客户经理吗?你刚才好像没说呀。”
我说:“可以更换,我刚才忘记说了。”
你紧跟着追问:“那么负责合同的销售人员,还有项目经理是不是也可以换呢?”
我说:“也可以,我自己都忘了写了。”
于是我们补充了这几个事件。同时,由于这三个领域事件不一定会出现,所以我们决定另起一行,也就是第一行表示主流程,包括必然发生的事件,第二行表示可选的事件。现在统一后,就变成了下面这个样子:

最后,我们把整个流程又仔细检查了一遍。你眼尖,又发现了一个遗漏的领域事件。员工分配到项目上以后,还可以下项目,所以应该有一个“员工已退出”事件。
好补充以后,最终结果就是下面这个样子:

现在,我们终于为项目管理流程,完成了“识别领域事件”这个步骤。
识别其他流程的领域事件
用同样的方法,可以识别其他流程的领域事件,这里就不一一重复了。下面这张图是我们识别出的所有领域事件:

在这张图里,你可以看到,有些业务规则在最开始的需求描述里是没有说明的,而是在咱们不断地讨论中,逐步澄清的。此外,我们还用橘红色的便利贴表示业务流程的名字,以便区分。
关于领域事件,我们还要注意下面这两点。
第一,不要把技术事件当成领域事件。领域事件一定要是领域专家所关注的,用的是业务术语。像数据库事务已回滚、缓存已命中之类的技术术语,不是领域事件,不在这个阶段讨论。
第二,查询功能不算领域事件。领域事件应该是对某样事物产生了影响,并被记录的事情。一般是某个事物的创建、修改和删除。还有一种情况是向其他人或者系统发消息,例如“通知邮件已发送”也算领域事件,因为接收方可能会通过进一步处理来影响某些事物。
而像“客户信息已查询”这些就不算领域事件,因为还没有对事物产生实际影响。不过,这并不代表查询功能不重要,查询功能也要以某种方式体现。这一点在后续的课程我们再讲。
到这里,我们就完成了事件风暴的第一步“识别领域事件”,后面两步“识别命令”和识别“领域名词”将在下一节课讲解。
总结
下面我们来总结一下。这节课,我们首先解释了用事件风暴之类的方法梳理需求的必要性,包括从头脑中挖掘需求、补充遗漏的需求、使业务人员和技术人员理解一致,以及辅助识别领域对象四点。
事件风暴是从识别领域事件开始的。“领域事件”是在业务过程中,业务人员关注的那些已经发生的事情。技术事件和查询功能都不算领域事件。领域事件意味着业务流程中每个步骤的结果。这种结果导向的思维方式更容易理清业务。事件风暴中的“事件”两个字就来源于领域事件。
识别领域事件的过程可以分成了两大步:第一步是参加的人,各自写出领域事件;第二步是一起讨论,统一理解。这种先发散,后收敛,反复迭代的过程实际上就是一种头脑风暴。
头脑风暴是一种常见的协作方式,可以让一群人一起通过思维的碰撞,分析问题,最终达成一致。事件风暴中“风暴”两个字就来源于“头脑风暴”。
在这个过程里,我们已经开始形成统一语言。所谓统一语言,英文是 Ubiquitous Language,是DDD中的一个核心模式。指的是业务人员和开发人员使用的语言要一致。语言是知识的载体。语言一致就意味着背后对领域知识的理解一致。统一语言贯穿了DDD的全过程。
同时,我们也开始识别业务规则。业务规则的处理,也会在后面继续讨论。
我们这节课不厌其烦地讲了识别领域事件的整个过程,是希望你能够体会到在真实的场景中,我们怎么通过不断地讨论,澄清误解、补充遗漏、发现业务规则。
一定要注意,“协作”才是事件风暴的精髓,而具体结果怎样呈现,反而是第二位的。当然,最好的学习方法不是听课,而是实践。所以呢,赶快找几个小伙伴,拿你手头的项目试一试,真正体会一下协作共创的乐趣。
思考题
1.今天识别的领域事件,主要是以“增加”的功能为主,你觉得需要把修改和删除的功能都列出来吗?
2.业务规则用便利贴写出来,时间久了可能不容易维护,你觉得有没有更好的办法呢?
好,今天的课程结束了,有什么问题欢迎在评论区留言。下一节课,我们继续完成事件风暴的另外两个步骤:识别命令和识别领域名词,为领域建模打下基础。
精选留言
2022-12-10 15:10:20
2.那怎么办?如果没有这么一位PO那我们就补位。那么问题就从与关键PO进行领域风暴编程了PO如何快速了解领域知识,沉淀认知概念。
3.那怎么做?
A.绘制干系人地图,通过与业务专家/客户项目负责人沟通,把当前参与领域活动所有的角色都定义出来。
B。与参与度最高的角色,一起梳理业务全景(第一次时间会比较长,需要尽量不遗漏),重心在提炼顶层关键业务阶段,和该角色在这个顶层业务阶段下的所有用户旅程(用户旅程要包含 绩效指标 耗时 频率 参与人数 痛点等多维数据)。
C.拿着这个顶层关键业务阶段去和相同角色的其他一线人员碰(这里有框架了,主要在确认认知准确性和挖掘遗漏点)。
D.拿着顶层关键业务阶段去和其他角色重复上诉 B、C两个步骤。刻画全角色的用户旅程,得到业务全景。
E.拿着业务全景去跟领导层沟通,汇报 + 达成共识。这个环节最主要的是识别出战略重心/关键目标。领域知识本身是没有偏向性的,企业的战略才有。做子域划分要定义核心域,这里的核心域定义和选择很大程度取决于领导层提供的战略方向/关键目标。
F.有了业务全景和关键目标,拿着这两件产物和业务专家过事件风暴。这样在事件风暴一开始就有框架和目标,最后事件流的产出,成效会好很多(因为一开始就有了边界和收敛的方向)。
到这里没PO补位PO的玩法就完了。接下来把后续工作步骤也补充下。
G.事件流本身聚焦在"关键写"流程,修改删除查询不会过多刻画。这么做的原因在于,事件流后续产出物是领域建模(我习惯四色建模),重心是识别关键模型、模型角色及模型间关联关系。这个阶段的模型产出是比较粗的粒度。
H.追加业务全景里面的删改查场景,进一步增加模型、丰富模型上的属性、调整模型类型。
I.拆分子领域(这里与建模其实是并行的,提取完业务知识和关键目标就可以做,这是问题空间的事情,而建模是解空间的事情。多数时候它们是交织开展的,虽然概念上做了区分,但现实里它们就是交织在一起的,相辅相成)。基于关键目标,确定阶段核心域。两条个人观点:战略会变核心域也会变;关注点在核心而不是边界。
J.将问题空间与解空间合并。把聚合按业务相关性分类到子域上。结合物理因素/复杂度/组织结构/安全/调用频率等等一系列因素圈限界上下文。
2022-12-10 09:59:11
1. 修改删除之类的,有相关的业务才需要列出来,比如合同签订了就只能违约,不能修改和删除,那就只有一个合同已违约,修改和删除甚至创建都一样是技术术语,事件风暴最好用业务术语。技术术语 创建,修改,删除 业务术语 添加(录入) 签订 违约等
2. 个人不觉得事件风暴是一种产出物,事件风暴只能做中间产物,产出物可以用多种方式记录,比如偏业务的用户旅程地图、服务蓝图 偏技术的UML 领域模型(带业务规则),这些图里面相对事件风暴更好记录,如果强行用事件风暴,觉得便利贴不好维护,可以推荐一波 BeeArt https://www.beeart.com/ 在线白板
2023-01-07 21:31:54
https://boardmix.cn/app/editor/3ywv0CZURp_x5wm2IDm8pQ?inviteCode=kjG6ak
2022-12-12 16:51:31
企业落地过程中,往往把事件风暴和头脑风暴混为一谈。
领域专家可能并不专业,往往谁的“权利大”谁说了算。
团队活动,参与人不明确,干系人选择性参与会议,比较佛系。
业务建模不关我的事,业务已经很清楚了,怎么做能不能实现是你们的事。
DDD是啥我们并不关心,对我们没有价值,没有DDD我们也做到了上市企业。
。。。
DDD实践是一个工程问题,践行时也是一个过程,在过程中只开一两次对齐会议是解决不了领域建模问题的。如果从利他角度来讲,在这个过程中的不同阶段每个人都可以受益,但不是同时受益,有可能要先解决哪部分人先受益的问题。
2023-02-02 23:03:58
What
Q1:什么是事件风暴?
是一种通过协助完成需求梳理的方法。
Q2:除了事件风暴之外,还有什么方法也可以帮助梳理需求?
用例,use case,传统需求梳理方法。
Why:
Q1:为什么要使用事件风暴来做需求梳理?
1、业务人员与开发人员之间会通过协助方式来完成,可以使双方对需求的理解达成一致、补充遗漏的需求。
2、辅助识别领域对象。
3、事件风暴是结果导向的思路来梳理需求,更容易把业务想清楚。(DDD大师的经验)
How
Q1:怎样进行事件风暴?
1、识别领域事件。
2、识别命令。
3、识别领域事件和命令中的名词性概念。(领域模型的基础)
整个过程是一个动态协助的过程。
Q2:怎样进行“识别领域事件”?
1、业务人员和开发人员双方写出自己理解的领域事件。
2、通过沟通、协助来迭代领域事件,明确业务规则,构建统一语言,最终达成一致的理解。
Q3:在识别领域事件中使用的关键概念有哪些?
业务规则、统一语言、必然的事件和可选的事件、业务流程的名称。
Q4:什么是领域事件?
业务过程中业务人员主要关注的业务结果。例如:项目管理过程中,客户已添加。
Q5:什么不是领域事件?
1、技术事件不是领域事件。例如:数据库已插入。领域事件是业务角度的事件。
2、查询功能不能算领域事件。例如:客户信息已查询,
How Good
DDD常识
1、在DDD中的各种命名,一般优先使用约定俗成的业务术语。
2023-04-25 09:12:18
2022-12-30 16:23:51
2022-12-22 15:55:32
2022-12-19 23:11:43
业务规则可以从文字说明量化为领域事件的属性,或者是一对多、多对多之类的关系,采用代码来表达。
2022-12-10 09:06:42
抓个虫:最后一幅图中有一个灰色便利贴:“只能在项目有小区内才能报工时”,应该是“只能在项目有效期内才能报工时”,编辑同志该打屁股,哈哈
思考题:
1. 如果修改和删除涉及重要的业务流程,我觉得应该列出来,但可以慢慢迭代,不必一次就思考的那么全;
2. 用实体便利贴确实不容易维护,可以建模完成后拍照,或者用一些工具比如draw.io画下来保存在电脑上,建模的时候投屏
2022-12-10 06:41:43
对事件的定义是什么,举个例子,刺客某日刺杀总统算不算一个事件?这个事件并不需要加上“已”才是事件。再举个例子,订单生成后要发送电子发票给客户,通常会说触发发送电子发票事件,这个事件可能尚未发生,但也是一个事件。
所以对于领域事件定义是什么,要素是什么?
加了“已”之后,更像一个结果,一个状态。相比而言“添加客户”比“客户已添加”能更好的表达事件。
2023-12-07 16:27:50
1.事件风暴的基于背景是什么,是基于系统流程还是业务流程,也就是说,事件风暴的事件是系统中会产生的事件,还是业务中会产生的事件?
比如说“合同已签订”,我觉得是站在业务的角度来说的,因为不会在系统签订合同,系统只能是录入签订好的合同,站在系统角度来说就是“合同已添加”。
那么同理“客户已添加”是站在系统角度来说的,业务不会说添加了一个客户吧,那么我就感觉“客户已添加”和“合同已签订”所基于的角度不同。
2.客户是什么时候绑定客户经理的,合同是什么时候绑定销售人员的,为什么在事件风暴里没体现出来,只有更换客户经理和更换销售人员
2022-12-17 16:54:58
事件风暴:
是什么?
在开发过程中(“捕获行为需求”):为了理解需求,我们首先要分析系统具有哪些功能,这些功能由什么人操作,会产生什么效果。
传统会用:“用例”
DDD用:事件风暴
怎么做?
识别领域事件:
● 找到业务流程中发生了哪些事情;
○ 这里就需要一定的业务领域知识,这个业务流程里需要做哪些事
○ 比如:海外支付,有些就是预授权+确定支付,而不是一步做了确认支付流程
● 业务流程中每个步骤引发的结果,关注结果
● 命名标准:完成时+被动语态,eg:订单已提交
○ 优先使用约定俗成的通用业务术语,eg:已立项代替项目已创建
● 误区:
a. 不要把技术事件(事务回滚)当做领域事件
b. 查询功能不算领域事件,是指这个事件对某个事物有了影响(事件创建、修改、删除)
识别命令:
进一步说明是什么角色,做了什么操作,导致上述事情的发生;
识别领域名词:
从领域事件和命令中找到名词性概念,为进一步的领域建模打下基础。
回答课后思考:
1. 需要列,如果业务有诉求就需要列,列全,也便于后面做其他分析需要
2. 换个地方,在线协作等工具
2022-12-11 16:27:44
2022-12-10 06:56:23
2024-11-14 23:57:26
2024-03-23 15:25:36
---
问题:员工分配放到项目管理,但企业管理不放到项目管理中。什么放进去什么不放进去,这个度是靠领域专家拿捏吗?还是有方法论呢?
2022-12-15 21:52:44
2022-12-11 14:40:00
2. 可以利用互联网的协作工具,例如白板
2025-05-11 15:04:06
1.业务流程怎么提现?
2.领域事件与用例很相似,两者之间有什么联系,又有什么区别?