03|事件风暴(上):怎样和业务愉快地聊需求?

上一讲,我们正式开始了第一个迭代,并简单分析了迭代一的需求。今天,咱们就要根据 DDD 的基本开发流程,使用事件风暴方法来进一步梳理需求。
你可能会问,上一讲的需求好像已经说得挺清楚了,为什么还要用专门的方法来梳理呢?
其实,在真实项目,尤其是敏捷项目里,领域专家很可能不会像我们上一讲那样,一开始就把需求都一一列出来,需求可能仅仅停留在领域专家的脑子里。所以,我们就需要一种方法,能够将这些头脑中的需求挖掘出来。
而且,即便领域专家已经把需求写出来,我们也很难保证没有遗漏,保证开发人员都彻底理解了。而事件风暴不仅能帮助我们尽量把需求补充完全,而且还能以协作的方式保证业务人员和技术人员对需求理解一致。
此外,事件风暴方法也能够帮助我们识别领域对象,这也是我们进行领域建模前的重要一步。尽管对于建模高手来说,通过“聊天”的方式就能把模型画出来,但对于多数开发团队而言,还是需要一种套路化的方法作为辅助,一步一步地做。
这节课我们从实践入手,让你真正掌握事件风暴的概念和具体操作。

事件风暴是怎么一回事?

那么,事件风暴是怎么来的呢?
一般来说,为了理解需求,我们首先要分析系统具有哪些功能,这些功能由什么人操作,会产生什么效果。这个过程传统上叫做“捕获行为需求”。
捕获行为需求的方法有好几种,在传统的软件工程中,最常用的方法是“用例”,也就是 Use Case。但是,Eric Evans 在《领域驱动设计》这本书里,并没有规定捕获行为需求的具体方法。直到 2013 年,一位叫 Alberto 的 DDD 专家提出了“事件风暴”,也就是 Event Storming。
这种方法简单易学,而且充分体现了 DDD 中沟通协作、统一语言等要点,所以逐渐开始流行起来。你可以先看看这张图,这里说明了事件风暴的主要过程:
03|事件风暴(上):怎样和业务愉快地聊需求?_第1张图片

这里的第一步是识别领域事件,在这一步,我们要找到业务流程中发生了哪些事情;第二步是识别命令,进一步说明是什么角色,做了什么操作,导致上述事情的发生;而第三步是识别领域名词,从领域事件和命令中找到名词性概念,为进一步的领域建模打下基础。这里每一步的具体做法和要点,我们后面都会详细介绍。
那么现在,咱们就来想象一下如何在真实的项目中一起做事件风暴。为了保证把细节讲清楚,我们会分为两节课进行,今天的课先聚焦于第一步,识别领域事件。
我再强调一句,由于事件风暴是一个动态的协作过程,不太容易通过文字表达,所以在看后面内容的时候,你一定要充分发挥想象力,让头脑中有“画面感”,脑补出咱们两个人唇枪舌剑,反复讨论的过程。

事件风暴的准备

不过,在正式开始事件风暴之前,我们还要先做一些准备工作。
首先是人员的准备。事件风暴要求业务和技术人员共同协作。业务人员,也就是之前说过的“领域专家”,在实践中一般由业务部门的专家,或者产品经理、PO(Product Owner)、BA(Business Analyst)等角色来担任。技术人员呢,首先要有架构师,其次也可以有技术经理,或者其他的开发人员、测试人员也可以参加。
第二是场地准备。我们需要找一个比较大的会议室,或者至少有一面足够长的墙。
最后是器材准备。我们需要几套彩色的便利贴,到时候我们会把事件风暴的主要内容写在上面。另外,通常还要一卷一开的大白纸,把这些白纸打横,一字排开,贴在会议室的墙上,用来贴便利贴。

事件风暴的第一步:识别领域事件

好,现在还是我来扮演产品经理,你来扮演架构师。而且假设我以前做过事件风暴,而你是第一次,所以我比你知道得多一点。
一开始,我先口头给你讲了一遍需求,你大概听懂了。然后我们就开始事件风暴的第一步:识别领域事件。
所谓领域事件,就是在业务过程中,业务人员要关注的那些已经发生的事儿。比方说,对于电子商务系统,订单已提交、商品已签收等等,都是领域事件。实际上,领域事件表示的是,业务流程中每个步骤引发的结果。事件风暴的作者认为,从结果入手来梳理需求,比从操作入手,更容易把业务想清楚。事件风暴中的“事件”两个字就来源于领域事件。
另外,咱们还要注意领域事件的命名,如果套用英语的语法来说,一般是完成时 + 被动语态。比如说,订单已提交,这个“已”字就是完成时,代表已经发生的事情。而订单已提交也可以说成订单已“被”提交,实际是被动语态,只不过一般把被字给省掉了。

识别“项目管理”流程的领域事件

接下来咱们一个一个业务流程来做。至于具体先做哪个流程,并没有特别的规定。不过由于项目管理这个流程比较长,我们就拿这个流程为例来讲吧。
首先,咱们花十来分钟时间,各自按照自己的理解,把项目管理中发生的各个领域事件,分别写在橙色便利贴上。然后按大致的时间顺序贴在墙上。每人贴一行。写出来以后大概是下面这个样子:
03|事件风暴(上):怎样和业务愉快地聊需求?_第2张图片
然后,就可以对比咱们两个人写得有什么不一样,再经过讨论得出一致的结果。现在,咱们从左到右看一下。
第一步就发现了一个小区别。你写的是“客户已创建”,我写的是“客户已添加”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第3张图片

那么你就会问我:“业务人员一般会说客户已创建还是客户已添加呢?”
我告诉你:“一般是说客户已添加,因为从业务的角度,客户本来就是存在的 ,不需要创建,只是把客户资料添加到我们的系统而已”。你表示同意。
然后我又叮嘱了一下:“以后添加客户的时候,都说添加这个词,别再说创建了。”这时候,其实我们已经是在建立“统一语言”了。统一后的结果是下面这个样子:
03|事件风暴(上):怎样和业务愉快地聊需求?_第4张图片
第二步,你写的是“签订合同”,我写的是“合同已签订”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第5张图片
一说你马上就反应过来了,刚才我们说过要用完成时和被动语态,“签订合同”是个动作,不是事件。所以达成一致后,结果变成下面这样:
03|事件风暴(上):怎样和业务愉快地聊需求?_第6张图片
下一步,你写的是“项目已创建”,我写的是“合同已生效”。不过我后面还有一步“立项”,应该和你的“项目已创建”是一回事,所以说明我比你多了一步“合同已生效”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第7张图片
于是你又问了:“合同签订以后不是马上就生效了吗,还要有一个额外的生效步骤吗?”
我解释说:“合同签订的时候未必马上生效,比如 1 月 1 日签了合同,但合同中可以约定,真正生效是在 2 月 1 日,所以需要一个单独的步骤让合同生效。”这时候,你知道了一条原来不知道的领域知识。
然后你又问了:“我写了项目已创建,但是你写的是已立项,你这种写法好像和其他的不太一致呀。”
我解释说:“虽然我们为领域事件命名的时候,常常用‘什么什么已什么什么’的形式,不过如果业务上已经有约定俗成的术语,我们就直接使用术语,这样更容易和业务沟通。现在业务觉得已立项是一个通用的术语,写成项目已创建反而显得生硬。”
现在你又知道了,在 DDD 中的各种命名,一般都优先使用约定俗成的业务术语。统一后的样子如下图:
03|事件风暴(上):怎样和业务愉快地聊需求?_第8张图片
再来看后面三步,这时我发现自己漏写了“项目已启动”。然后我们再比较了一下“项目已终止”和“项目已结束”两个说法,觉得“项目已结束”更符合业务术语。而“合同已结束”这一步,咱们俩是一样的。
03|事件风暴(上):怎样和业务愉快地聊需求?_第9张图片
不过我在“项目已结束”前面还多了一个“员工已分配”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第10张图片
于是你又问我:“刚才你讲需求的时候,好像是把员工分配作为一块单独的需求来讲的,不属于项目管理这个流程吧?”
我想了想,说:“员工分配背后的业务逻辑有点复杂,所以之前单独拿出来讲,其实员工分配是项目运作中的一个重要环节,放在项目管理中也没毛病。”你对此表示认可。
这时我又补充了一点:“员工分配到项目的时候,要填入预计的投入工作量的百分比,一个人可以同时上多个项目,但预计的投入百分比总和不能超过 100%。这种逻辑一般叫业务规则,为了避免忘记,咱们也写在便利贴上吧。”
于是我们把业务规则写在浅灰色便利贴上,贴在“员工已分配”事件的下方。经过这几步,结果变成了下面这个样子:
03|事件风暴(上):怎样和业务愉快地聊需求?_第11张图片

再下一步,你多了一个“客户已终止”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第12张图片
我解释说:“客户可以在系统中长期存在,以便不断挖掘商机,一般不必专门进行终止。理论上说,万一客户破产了,是应该终止,不过目前业务上还没有这个需求,这一点可以以后再考虑。”于是我们把“客户已终止”拿掉了。
然后你又发现,我的流程中最后还多了一个“客户经理已更换”。
03|事件风暴(上):怎样和业务愉快地聊需求?_第13张图片
你有点惊讶地问:“可以更换客户经理吗?你刚才好像没说呀。”
我说:“可以更换,我刚才忘记说了。”
你紧跟着追问:“那么负责合同的销售人员,还有项目经理是不是也可以换呢?”
我说:“也可以,我自己都忘了写了。”
于是我们补充了这几个事件。同时,由于这三个领域事件不一定会出现,所以我们决定另起一行,也就是第一行表示主流程,包括必然发生的事件,第二行表示可选的事件。现在统一后,就变成了下面这个样子:
03|事件风暴(上):怎样和业务愉快地聊需求?_第14张图片
最后,我们把整个流程又仔细检查了一遍。你眼尖,又发现了一个遗漏的领域事件。员工分配到项目上以后,还可以下项目,所以应该有一个“员工已退出”事件。
好补充以后,最终结果就是下面这个样子:
03|事件风暴(上):怎样和业务愉快地聊需求?_第15张图片

现在,我们终于为项目管理流程,完成了“识别领域事件”这个步骤。

识别其他流程的领域事件

用同样的方法,可以识别其他流程的领域事件,这里就不一一重复了。下面这张图是我们识别出的所有领域事件:
03|事件风暴(上):怎样和业务愉快地聊需求?_第16张图片
在这张图里,你可以看到,有些业务规则在最开始的需求描述里是没有说明的,而是在咱们不断地讨论中,逐步澄清的。此外,我们还用橘红色的便利贴表示业务流程的名字,以便区分。
关于领域事件,我们还要注意下面这两点。
第一,不要把技术事件当成领域事件。领域事件一定要是领域专家所关注的,用的是业务术语。像数据库事务已回滚、缓存已命中之类的技术术语,不是领域事件,不在这个阶段讨论。
第二,查询功能不算领域事件。领域事件应该是对某样事物产生了影响,并被记录的事情。一般是某个事物的创建、修改和删除。还有一种情况是向其他人或者系统发消息,例如“通知邮件已发送”也算领域事件,因为接收方可能会通过进一步处理来影响某些事物。
而像“客户信息已查询”这些就不算领域事件,因为还没有对事物产生实际影响。不过,这并不代表查询功能不重要,查询功能也要以某种方式体现。这一点在后续的课程我们再讲。
到这里,我们就完成了事件风暴的第一步“识别领域事件”,后面两步“识别命令”和识别“领域名词”将在下一节课讲解。

总结

下面我们来总结一下。这节课,我们首先解释了用事件风暴之类的方法梳理需求的必要性,包括从头脑中挖掘需求、补充遗漏的需求、使业务人员和技术人员理解一致,以及辅助识别领域对象四点。
事件风暴是从识别领域事件开始的。“领域事件”是在业务过程中,业务人员关注的那些已经发生的事情。技术事件和查询功能都不算领域事件。领域事件意味着业务流程中每个步骤的结果。这种结果导向的思维方式更容易理清业务。事件风暴中的“事件”两个字就来源于领域事件。
识别领域事件的过程可以分成了两大步:第一步是参加的人,各自写出领域事件;第二步是一起讨论,统一理解。这种先发散,后收敛,反复迭代的过程实际上就是一种头脑风暴。
头脑风暴是一种常见的协作方式,可以让一群人一起通过思维的碰撞,分析问题,最终达成一致。事件风暴中“风暴”两个字就来源于“头脑风暴”。
在这个过程里,我们已经开始形成统一语言。所谓统一语言,英文是 Ubiquitous Language,是 DDD 中的一个核心模式。指的是业务人员和开发人员使用的语言要一致。语言是知识的载体。语言一致就意味着背后对领域知识的理解一致。统一语言贯穿了 DDD 的全过程。
同时,我们也开始识别业务规则。业务规则的处理,也会在后面继续讨论。
我们这节课不厌其烦地讲了识别领域事件的整个过程,是希望你能够体会到在真实的场景中,我们怎么通过不断地讨论,澄清误解、补充遗漏、发现业务规则。
一定要注意,“协作”才是事件风暴的精髓,而具体结果怎样呈现,反而是第二位的。当然,最好的学习方法不是听课,而是实践。所以呢,赶快找几个小伙伴,拿你手头的项目试一试,真正体会一下协作共创的乐趣。

思考题

  1. 今天识别的领域事件,主要是以“增加”的功能为主,你觉得需要把修改和删除的功能都列出来吗?
  2. 业务规则用便利贴写出来,时间久了可能不容易维护,你觉得有没有更好的办法呢?
    好,今天的课程结束了,有什么问题欢迎在评论区留言。下一节课,我们继续完成事件风暴的另外两个步骤:识别命令和识别领域名词,为领域建模打下基础。

你可能感兴趣的:(DDD,java)