DDD-2- 事件风暴
大部分整理至极客时间的《手把手教你落地 DDD》专栏。
1、主要过程
识别领域事件 --> 识别命令 --> 识别领域名词
2、前期准备
人员
事件风暴要求业务和技术人员共同协作
场地
够长
器材
便利贴,规定不同颜色表示不同词性
3、核心步骤
第一步:识别领域事件
关键:
找到业务流程中发生了哪些事情
业务流程中每个步骤引发的结果,使用【完成时 + 被动语态】表示
实操:
参加的人各自写出领域事件
一起讨论,统一理解
第二步:识别命令
关键
进一步说明是什么角色,做了什么操作,导致上述事情的发生
注意
首先,有些命令可能没有查询数据
其次,还有的命令会有多个查询数据
另外,还有的命令会有多个执行者
第三步:识别领域名词
关键:
从领域事件和命令中找到名词性概念,为进一步的领域建模打下基础
实操
把围绕同一个名词的命令、事件、执行者、查询数据摆在一起
第二步,把领域名词写在大一点的黄色便利贴上,贴在每堆便利贴的中间
4、注意事项
第一,不要把技术事件当成领域事件
第二,查询功能不算领域事件
第三,“协作”才是事件风暴的精髓
第四,在 DDD 中的各种命名,一般都优先使用约定俗成的业务术语
5、关键元素对建模和实现的用处
领域事件作用
从代码实现的角度来看,领域事件一般会对应一段代码逻辑,这段逻辑可能会最终改变数据库中的数据
另外,在事件驱动的架构中,一个领域事件可能会表现为一个向外部发送的异步消息。
命令的作用
领域建模时,我们可以通过对命令的走查(walkthrough),细化和验证领域模型
在实现层面,一个命令可能对应前端的一个操作,例如按下按钮;对于后端而言,一个命令可能对应一个 API
命令的执行者
在领域建模时,执行者可能本身就是一个领域对象,也可能是领域对象充当的角色,或者是权限管理中的一个角色。
查询数据
每个查询数据,就对应着一个查询功能,不过,这里的查询数据是为了某个命令服务的。
系统中可能还有一些单纯的查询功能,并不与某个特定的命令绑定。这些查询功能不会通过事件风暴识别出来,需要单独进行分析。
领域名词
识别领域名词的最终目的是要找到领域模型中的对象
领域名词不等价于领域模型中的对象,有可能只是一个对象充当的角色,或者对象的属性
这些名词将成为领域建模的“素材”
6、常见问题
第一,在事件风暴里是否要列出所有的领域事件和命令?
列出所有领域事件和命令并没有原则上的错误,但这样做会让结果变得繁琐,反而让人抓不住重点。
在事件风暴里只列出主要的、足以用于表达和交流领域知识的步骤
可以结合用户故事或者传统的功能列表等方法保存系统功能的全集,保证功能不漏
第二,各个领域事件需要体现严格的时间顺序吗?
只需要按照大致的顺序
如果要体现严格的时间顺序,需要用到更复杂的符号,这会使事件风暴变得非常繁琐。
如果要体现严格的时间顺序,我们可以用流程图、用顺序图等方法,但事件风暴不必关注这一点。
第三,每个步骤的颗粒度应该有多大?
这里说的步骤,指的是一对领域事件和命令。这就要考虑从业务的角度,我们是把每个小步骤都当作独立的一个事务来看待,还是把它们合起来作为同一个事务。另外,可以设想,如果每个小步骤都向外界发出一个领域事件,对系统后续的功能是不是有意义有时仍然会有模棱两可的情况,这时,原则上宜粗不宜细。可以先采用比较大的颗粒度。后面必要的时候,再拆细,就可以了。
第四,事件风暴适用于所有项目吗?
第一个层面,事件风暴主要应用在需求不清晰,或者理解不统一的情况下,通过协作的方式理清业务、达成一致,所以通常对于新项目比较适用。
第二个层面,即便在适用的场合,事件风暴也不是唯一的方法,我们还可以用用例分析、用户故事等方法实现类似的目的。只要抓住协作、统一语言等等要点,这些方法都可以用在 DDD 的项目里。
第五,怎么保存和维护事件风暴的结果?
如果事件风暴的内容最终会反映到用户故事、用例、功能列表等产出物中,而这些产出物会进行维护,将电子化的结果作为一种中间产物保存就可以了
表格的形式来保存
第六,怎么保存领域规则?
领域规则表领域规则表(但维护成本极高,还是以产品的 PRD 为主,若是技术团队主导,可尝试)
评论