识别领域事件 – ThoughtWorks 洞见

2018/9/23 posted in  Reactive

https://insights.thoughtworks.cn/recognize-domain-event/

随着微服务架构的兴起,微服务设计与拆分的的最佳实践 DDD 已然成为大家讨论与实践的热点,整个行业都在探索如何用 DDD 建模来实现微服务设计。事件风暴作为最接地气的实践,在不同的项目中野蛮生长,不断演进,今天已经渐渐成熟。作为事件风暴的灵魂——领域事件,值得我们投入更多的精力去设计与打磨。

领域事件是用特定方式 (已发生的时态) 表达发生在问题域中的重要事情,是领域通用语言 (UL) 的一部分。为了方便理解这个概念,这里举一个宠物的例子:如果做为宠物主人,你的问题域是如何养好一只猫,那么是不是已经打了疫苗,给宠物饲喂食物等将成为你关注的事情,领域事件会有:疫苗已注射,猫粮已饲喂等。如果你是宠物医生,问题域是如何治好宠物的病,关注的事情是宠物的身体构成,准确的诊断宠物病情,对症下药,领域事件会有:病情已确诊,药方已开治。虽说二者关注的都是宠物,在不同的问题域下领域事件是不同的。

DDD 的提出者和圈内的大师先后提到领域事件在领域建模中的价值,前沿实践者们已经开始应用领域事件来表达业务全景。在 DDD 建模过程中,以领域事件为线索逐步得到领域模型已经成为了主流的实践,即:事件风暴。

事件风暴是以更专注的方式发现与提取领域事件,并将以领域事件为中心的概念模型逐渐演化成以聚合为中心的领域模型,以快速可落地的方式实现了 DDD 建模。

对于高质量的事件风暴,首先要解决识别领域事件的问题,理想的情况下领域专家和研发团队一起参加事件风暴,从业务的视角去分析涉众关心的领域事件,短时间内高度可视化交流,集中思考,快速发散收敛形成所有参与者一致认可的领域事件集合。我在多个项目上实现事件风暴后,总结了一些坑和应对办法,供大家参考:

1. 组织没有领域专家

对问题域有深刻见解的主题专家称为领域专家,在大多数组织中没有这个角色,当 DDD 建模需要领域专家支持时,组织往往找业务部门的业务人员,BA,产品经理或在这个领域有多年开发经验的 DEV 来充当。

这些一线业务人员和开发团队都清楚有什么功能,但往往不清楚为什么有这些功能。举个例子:如果我们的问题是打开一瓶红酒,你去调研每天都会打开酒瓶的 waiter, 给你的答案是:开瓶器。但换做领域专家的视角来看,会回归问题的本质,如果我们希望打开酒瓶,需要把瓶塞移除,移除瓶塞的方式有多种,包括推,撬与拉拽,对于拉拽可能基于吸力或螺旋拉拽,下面右图的开瓶器只不过是螺旋拉拽的一种解决方案。领域专家应该对问题域及其中的各种可行方案有更深入的理解。

在辅导团队的过程中,为了弥补这部分视角的缺失,往往会在事件风暴之前,组织业务愿景和场景分析,与被指派的业务干系人对齐业务愿景,一起分析业务场景背后的问题域,找到问题域的本质后再展开事件风暴。

2. 面向复杂业务系统的事件风暴

高效事件风暴的规模推荐 5-8 人,超过 8 人的事件风暴就会出现讨论时间过长,部分成员参与度不高,业务之间的相关度弱等问题。在一个以支付中台为主题的事件风暴中,对于电商商城的支付与理财产品的支付相关性就很弱,各自关心的是自己的业务,让这两组人在一起讨论,在得到同样产出的情况下,会花费双倍的时间。

在处理复杂问题时,一个有效又好用的方法就是分而治之,对于复杂系统的事件风暴也是同样如此。在业务干系人达到一定规模后,将业务干系人分成多组,组织多轮事件风暴,迭代演进领域模型也是一种不错的选择。

分组的基本原则应以业务线为线索,如果目标系统的业务干系人在同一个业务主线上,每一组人代表业务主线上的一个环节 (如下图),这种情况按照业务结点进行分组即可。对于业务相对简单的结点,可以将其与相临结点合并组织事件风暴。

当目标系统是多条业务线上的某几个公共结点,一般业务中台会出现这种情况,如支付中台要为不同的业务部门 (保险,商城,还信用卡等) 提供支付服务,如下图中的虚线部分。这类业务往往结点之间的边界并没有那么清楚,系统做什么与不做什么只有在梳理完整条业务线才能确认下来,这种情况按每条业务线分组展开事件风暴,然后针对多组产出结果进行统一业务概念抽象,建立系统边界内的统一事件流。

3. 业务代表或领域专家用自己的语言表达业务

事件风暴的第一个环节是让参与者头脑风暴,各自找出业务干系人关注的领域事件,对于业务干系人来讲,往往不适应把自己理解的业务按领域事件的方式表达出来,他们看到一串领域事件,也不觉得这种表达方式比传统方式直观,在这种情况下,我们就需要考虑如何引导业务共同输出领域事件。留心领域专家在表达需求过程中的一些模式:

1\. 当…
2\. 如果发生…
3\. 当…的时候请通知我
4\. 发生…时

通过模式中的关键字转换成领域事件,按时间顺序排序后,基于商业模式与价值定位与领域专家讨论领域事件,以统一的语言与统一的业务视角修正并验证领域事件。高质量的领域事件定义自然是清楚的,是可以找到问题域中的某个 actor 是关注它的,通过讲述领域事件是可以体现商业价值的。

4. 事件风暴可能识别不出来所有领域事件

通过事件风暴可以快速把整个问题域主线梳理出来,这样的产出是相当的高效和有价值,但对于正在尝试用事件风暴成果代替传统交付物的组织,往往会质疑事件风暴是否可以发现所有领域事件。

试考虑一个投资者,为一座摩天大楼的建造提供资金,投资者未必对建造过程的细节感兴趣,材料的选择及各种工程细节会议对于建造者来说是很重要的活动,对于投资者来讲,感兴趣的是良好的投资回报,保护投资免受风险,较为务实的投资者会设立明确的里程碑,每个里程碑通过后再做下一次注资。例如,在项目开始时,提供适量资金进行建筑设计工作。当建造事宜被批准时,再为项目提供较多的资金以进行设计工作。在设计通过评审通过后,才拔给更大量的资金,以便建造者破土动工。梳理得到事件如下:

系统建模同理,我们不关注所有事件,仅关注对干系人解决特定问题有价值的事件,并且这个特定问题应该已经在项目初期,业务愿景梳理的过程中在组织内达成了共识,就像上述投资者关注的问题一样清楚,在业务场景梳理与事件风暴的过程中,不断还原具体过程,以确保识别出的活动或事件真正可以解决业务问题。所以在事件风暴的过程中,并不需要担心是不是找出所有领域事件,只要真正解决了业务问题就好了。

另外,当开始采用新的方法论时,实践过程与角度都有差别,旧有体系的交付物不适用是常有的情况,重点关注的新的方法会不会以更简洁的方式解决实际问题。在存疑的风险处,活学活用新方法的交付物能够让组织更顺利的落地,当然必要的开发过程与交付物改进也是需要的,即可以更高效的完成设计工作,也能够让团队更专注在问题上。

总结

有人说微服务的设计与拆分是一门艺术,经验性的成份占了很大比重。当我们准备基于经验来做微服务的设计决策时,结合业务愿景,找出问题域内所有业务干系人真正关心的领域事件,展开完整的事件风暴,循序渐进的让场景变得更加具体,让经验与艺术在生动的问题域之中得到最大的发挥。

另一方面,有效地识别领域事件,既统一了语言,又助力在模型中体现出业务价值部分,为设计关注业务价值的领域模型打下了坚实的基础。