一家大型跨国企业收购了另一家大型企业的的关键业务软件系统,并决定用半年时间在上面进行定制开发,来适应新的需求。这个收购貌似让前者能快速开展新业务,但对于其开发团队来说,这不亚于是一场噩梦的开始:没有一位开发人员能够说清这个由多个团队合作开发的庞大系统从头到尾的业务全貌。在没有人能说得清业务需求的情况下,开发团队如何进行开发?
作为辅导这些企业进行敏捷和DevOps转型的咨询师,这几年来我一直在思考这个问题,期间做了一些努力来尝试回答,但成效总是有点差强人意。直到2017年12月8日我在“领域驱动设计中国峰会2017”大会参加了Event Storming 之父 Alberto Brandolini授课的一天“事件风暴工作坊”上午的“探索业务全景”(Big Picture Exploration)环节之后,才让我有信心解决这个难题。
工作坊上午的“探索业务全景”环节,能让说不清遗留系统需求的开发团队很快了解业务需求。适合新团队接手遗留系统、团队有大量新成员加入、业务发生很大变化等场景。以下是实施步骤:
准备物料
准备各种颜色和尺寸的报事贴(详见下文),给工作坊参加者每人一支Sharpie记号笔。可以准备长长的一大卷白色画卷纸贴在墙上,在上面贴报事贴,以便方便地搬运报事贴。邀请包含领域专家在内的团队所有成员参加
团队所有成员包括业务、开发、测试、运维等各个角色,其中“知道答案”的领域专家是必不可少的。下文的工作坊实例是要探索Brandolini的培训机构销售培训课程的业务。-
贴领域事件(Domain Event, 橙色)
请领域专家贴第一张他/她最关心的领域事件。在报事贴上用类似”票已售出“的句式来写领域事件。然后大家同时分头各自写这个事件之前和之后发生的其他事件,并按发生的事件顺序从左到右排序。
-
贴热点信息(Hot spot, 深粉)
如果发现某些事件在业务上需要额外注意,比如需要花大量时间培养新入行的培训师,那么就可以在“已与新入行的培训师联系”事件边上贴一个粉红的报事贴,上写”要花时间“。
-
贴业务子域边界(Boundary, 黄色胶带)
等大部分领域事件贴完后,就在其中一些关键时点,用黄色胶条来分割子域边界。比如在“培训课程已发布“右边贴一个黄色胶条,在“培训课程已交付”的右侧再贴一个黄色胶条。这样两个胶条就划分了3个业务子域——培训课程准备子域、培训课程售票与交付子域、培训课程售后子域。
-
贴核心业务子域(Subdomain, 蓝色)
识别橙色领域事件流中属于同一核心业务范畴的相邻的事件,并在它们的边上贴一个蓝色报事贴,写上核心业务子域的名字,比如“开具发票”。注意,此时不要移动橙色的领域事件。如果同样的核心业务子域出现在事件流的两个不同时点,那么就写两个相同的蓝色报事贴各自贴到相应位置。
-
贴参与领域事件的人(People, 黄色小报事贴)
在橙色的领域事件边上用黄色报事贴,贴参与该事件的人,上面可以写这个人的姓名或角色,比如约见新入行培训师的培训机构老板Alberto。
-
贴外部系统(External System, 浅粉)
在相应的领域事件边上,用浅粉报事贴,贴这些事件所依赖的外部系统。比如发布培训课程所需要的Eventbrite网站。
-
贴新的价值或商业机会(Opportunity, 浅绿)
在相应的领域事件边上,用浅绿报事贴,贴此处可能存在的商业机会。比如在“培训证书已打印”边上,贴一个制作“电子证书”这样一个新商业机会。
-
投票评选业务瓶颈(Bottleneck, 画有箭头的蓝色竖条报事贴)
每人一票,在你认为当前在业务上表现很糟糕或很有争议的地方上贴一个画有箭头的蓝色竖条报事贴。比如在“培训课程描述不抓眼球”边上贴箭头。那些获得最多箭头的瓶颈,就是今后开发工作的重点。因为根据约束理论,只有突破了这些最大的瓶颈,才能获得全局优化。
说不清遗留系统需求的开发团队,就好比说不清使命的军队一样,无法高效行动。要想在新团队接手遗留系统、团队有大量新成员加入、业务发生很大变化等场景下,让不熟悉业务的团队成员快速了解需求,可以召集包括领域专家、业务、开发、测试、运维在内的团队所有成员参加一个“探索业务全景”的工作坊,用每个人贴报事贴的形式来讨论和梳理现有的业务,最终让团队了解需求,达成共识,以便维护实现这些需求的遗留代码。另外还能识别当前系统的业务瓶颈,确定下一步开发工作的重点。
步骤如下:
- 准备物料
- 邀请包含领域专家在内的团队所有成员参加
- 贴领域事件(橙色)
- 贴警告信息(深粉)
- 贴业务子域边界(黄色胶带)
- 贴核心业务子域(蓝色)
- 贴参与领域事件的人(黄色小报事贴)
- 贴外部系统(浅粉)
- 贴新的价值或商业机会(浅绿)
- 投票评选业务瓶颈(画有箭头的蓝色竖条报事贴)
事件风暴之父工作坊下午的“软件开发设计”环节,可以让开发团队了解系统应该具备的领域模型及其交互关系,为编写单元测试进而驱动重构提供指导。下一篇博客将会对此进行讨论。敬请关注。