本篇BLOG为DDD流程的第一步,在模型的建立阶段,领域专家与技术人员通过业务事件风暴进行需求分析,也叫做行为需求捕获。
事件风暴目的
在真实项目,尤其是敏捷项目里,领域专家很可能不会一开始就把需求都一一列出来,需求可能仅仅停留在领域专家的脑子里。即便领域专家已经把需求写出来,我们也很难保证没有遗漏,保证开发人员都彻底理解了。而事件风暴不仅能帮助我们尽量把需求补充完全,而且还能以协作的方式保证业务人员和技术人员对需求理解一致
事件风暴准备
在正式开始事件风暴之前,要先做一些准备工作,包括人员准备与场地准备,也就是把参与方拉齐,组会进行讨论。
人员准备
事件风暴要求业务和技术人员共同协作。
- 业务人员,也就是领域专家,在实践中一般由业务部门的专家,或者PM、PMO、BA等角色来担任。
- 技术人员,首先要有架构师,其次也可以有技术经理,以及其它的RD、QA、FE
在商户的实践中,我们的领域专家需要有PM、PMO、BA、PA、运营、业务策略等角色,而技术人员需要部门负责人及各方向核心RD
场地准备
找个会议室,在白墙上或者在线协作站点上进行绘制。
事件风暴步骤
事件风暴主要有三个步骤,第一步是识别领域事件,在这一步,我们要找到业务流程中发生了哪些事情;第二步是识别命令,进一步说明是什么角色,做了什么操作,导致上述事情的发生;而第三步是识别领域名词,从领域事件和命令中找到名词性概念,为进一步的领域建模打下基础
详细的XMIND展开如下
1 识别领域事件
业务事件风暴的第一步是识别领域事件
什么是领域事件
所谓领域事件,就是在业务过程中,业务人员要关注的那些已经发生的事儿,实际上,领域事件表示的是,业务流程中每个步骤引发的结果,这种结果导向的思维方式更容易理清业务。命名一般是完成时 + 被动语态,例如【门店已联网】
领域事件识别步骤
领域事件识别步骤是先发散再收敛,分为两个步骤:
- 参加的人按照自己的理解,各自写出领域事件
- 一起讨论,统一理解看如何明确一个领域事件,明确的过程一般分为三种:对同一事件形成统一语言; 互相查漏补缺对方的事件;关注必然事件,同时枚举可选事件和业务规则
1 对同一事件形成统一语言
例如对于客户添加和创建形成统一认知,业务上用添加更合适,创建是个数据的概念,在此阶段用业务概念表达更合适,这样就已经是在建立“统一语言”了
2 互相查漏补缺对方的事件
查漏补缺对方的业务事件梳理,例如其实合同签订的时候未必马上生效,比如 1 月 1 日签了合同,但合同中可以约定,真正生效是在 2 月 1 日,所以需要一个单独的步骤让合同生效,还有个生效事件,
3 关注必然事件,同时枚举可选事件和业务规则
有些领域事件的运行需要基本规则,所以需要增加业务规则,还有一些事非必选的业务事件,另起一行描述
领域事件识别注意事项
识别领域事件的过程中有两个重要的注意事项
- 不要把技术事件当成领域事件,领域事件一定要是领域专家所关注的,用的是业务术语。像数据库事务已回滚、缓存已命中之类的技术术语,不是领域事件
- 查询功能不算领域事件,领域事件应该是对某样事物产生了影响,并被记录的事情。一般是某个事物的创建、修改和删除、以及消息发送等
例如客户信息已查询”这些就不算领域事件,因为还没有对事物产生实际影响。不过,这并不代表查询功能不重要,查询功能也要以某种方式体现
识别领域事件的目的
识别领域事件的主要目的是明确数据变更内容和规范,领域事件最终会改变数据库中的数据;同时在事件驱动架构中一个领域事件可能会表现为一个向外部发布的异步消息
2 识别命令
业务事件风暴的第二步是识别命令
什么是命令
所谓命令(command),就是引发领域事件的操作,我们可以通过分析领域事件得到
命令的识别步骤
识别命令有三个步骤。除了识别出命令本身以外,我们通常还要识别出谁执行的命令,以及为了执行命令我们要查询出什么数据
1 识别命令
识别命令本身,例如对于领域事件【合同已签订】,对应的命令就是【签订合同】
2 识别命令执行者(人(人的角色)还是系统)
比方说签订合同的命令执行者是销售,注意如果命令执行者是人,那么命令执行者是角色名词而不是具体的人名
3 为了执行命令需要查询的数据有哪些
有的命令会有多个查询数据。比如说为项目分配员工,要查出项目和员工两个信息
识别命令的目的
主要有以下三个目的,明确操作功能点,帮助识别领域对象和权限管理角色,查漏查询功能点
- 领域建模时,我们可以通过对命令的走查(walkthrough),细化和验证领域模型。在实现层面,一个命令可能对应前端的一个操作,例如按下按钮;对于后端而言,一个命令可能对应一个 API
- 识别领域对象或进行权限管理在领域建模时,命令的执行者可能本身就是一个领域对象,也可能是领域对象充当的角色,或者是权限管理中的一个角色
- 帮助保证查询操作不遗漏,每个查询数据,就对应着一个查询功能
3 识别领域名词
业务事件风暴的第三步是识别领域名词
什么领域名词
领域名词,指的是从命令、领域事件、执行者、查询数据里找到的名词性概念
领域名词的识别步骤
找到领域名词的方法是:
- 1 把围绕同一个名词的命令、事件、执行者、查询数据摆在一起
- 2 把领域名词写中间放大,命令、事件、执行者、查询数据围绕在旁边
识别领域名词的目的
识别领域名词的目的帮助找到领域模型中的对象,当然在这一步里识别出的名词,虽然很可能就是领域对象,但也未必。一个名词有可能只是一个对象充当的角色,或者对象的属性,还有些名词需要经过合并或拆解后,才是合理的领域对象
事件风暴产出
事件风暴结束后,我们需要将讨论结果落下来方便回溯,有两项内容需要记录
1 事件风暴结果
使用电子表格描绘事件风暴的结果
2 业务规则明细
使用电子表格记录业务规则明细
事件风暴常见问题
有如下几个重点问题需要明确
1 事件风暴里是否要列出所有的领域事件和命令
为了保证简洁,在事件风暴里只列出主要的、足以用于表达和交流领域知识的步骤,不必列出所有的领域事件和命令,例如签订合同、生效合同等等。而像修改合同和删除合同这样的步骤是显而易见的,可以结合用户故事或者传统的功能列表等方法保存系统功能的全集
2 各个领域事件需要体现严格的时间顺序吗
各个领域事件不需要体现严格的时间顺序,只需要按照大致的顺序,贴出领域事件就可以了,我们应该关注点分离。如果要体现严格的时间顺序,我们可以用流程图、用顺序图等方法,但事件风暴不必关注这一点
3 每个领域事件及命令的颗粒度应该有多大
每个步骤(一对领域事件和命令)的颗粒度原则上宜粗不宜细,可以先采用比较大的颗粒度。后面必要的时候,再拆细,就可以了。
例如:“签订合同”这个命令,在具体操作的时候,可能分成录入合同基本信息、录入合同明细、上传附件等等更小的步骤
总结一下
事件风暴不仅能帮助我们尽量把需求补充完全,而且还能以协作的方式保证业务人员和技术人员对需求理解一致。实践过程中有点儿像模型推演,先识别流程,例如入驻流程,然后识别领域事件,例如【门店已联网】,同时明确业务规则,门店一旦有了联网时间不能重置;再识别命令,例如A+开启导致门店联网,同时明确命令执行者是系统,执行时需要查询门店信息。当然可能还有可选领域事件,例如【门店维护人变更】不影响主流程。诸如此类串联完一系列领域事件、命令、查询、执行者之后总结出了【门店】这个领域名词。一个深的体会是过程中的UL语言建立以及结果导向从事件倒推命令、查询,执行者的梳理方式,实践中需要通过事件风暴表和业务规则留存。