DDD你真的理解清楚了吗?DDD与敏捷的结合

DDD在敏捷团队中的实践

大家好,我是范钢老师。上一期我们谈到了DDD有很多种实践方法,这些实践方法能够帮助我们在纷繁复杂的业务中,顺利地提取领域对象、形成领域模型。然而,不同的团队有各自不同的开发模式,因此可以根据自身的情况,选择不同的实践方法来实践DDD。这里不同的开发模式,大致就可以分为敏捷开发模式与传统开发模式。今天,我们就来谈谈敏捷团队采用敏捷开发模式,该如何实践DDD。

2001年,17位软件开发领域的领军人物,共同发表了《敏捷宣言》,提出了四个核心价值观和12条原则,从而开启了无数软件研发团队的敏捷转型。在这四个核心价值观中,提出了个体与互动高于流程与工具、能工作的软件高于详尽的文档、客户合作高于合同谈判、响应变化高于遵循合同。基于这样的思想,在DDD实践时,最适用的就是“事件风暴”的实践方法。

采用事件风暴法,不是一开始就大量编写需求文档,而是通过事件风暴会议来互动并探索需求,形成更加轻量级的领域模型作为输出物。事件风暴会议就成为了敏捷开发中迭代计划会议前的准备会议。众所周知,敏捷开发将整个开发过程划分成了无数个小的迭代,每个迭代有2-3周。在每个迭代即将结束的最后一周,各个开发团队一方面总结此次的开发成果,将这些成果形成可运行的软件予以展示。另一方面,则开始为下一个迭代周期进行准备。准备什么呢?通过一系列的事件风暴会议,梳理下一阶段的业务需求,形成领域模型,划分限界上下文,进而划分子系统和微服务。

各个团队不仅要梳理各自的领域模型,还要通过限界上下文的划分,形成上下文地图,为各个团队间的接口做好准备。只有通过这样的一系列梳理,各个团队都准备好了各自的领域模型,然后再开始召开迭代计划会议,一方面彼此独立地制订各自的迭代开发计划,另一方面又要对齐相互的开发周期,既要相互协作,接收对方的接口需求,又要站在全局的角度,在最短的时间完成客户最急需的功能。这时,领域驱动与敏捷开发如何完美地融为一体,让彼此独立又相互协作的多个团队高效地工作,就成为DDD实践的核心与关键。我们就通过上一期的那个在线订餐系统进行一次演练。

在上一期的在线订餐系统中,我们通过事件风暴会议的梳理,形成了以上的分析结果。与此同时,又通过限界上下文的划分,划分为了“下单上下文”、“接单上下文”与“派送上下文”,以及与它们相关的 “用户上下文”、“饭店上下文”等支撑域。通过这样的划分,就将开发团队划分为了“下单团队”、“接单团队”、“派送团队”、“用户团队”和“饭店团队”。除了这些面向业务的特性团队,还要有面向技术的架构团队,提供技术平台的支持。

团队组织形式确定下来了,每个团队彼此独立地就开始梳理并形成各自的领域模型。当然,在这个过程中,一些业务比较复杂,也可以再召开事件风暴会议,对某些具体模块进行分析。事件风暴会议的目的就是为了梳理并形成领域模型。在梳理领域模型的同时,各个团队也要关注各自的上下文地图,即我要与哪些上下文会形成交互,应当是怎样的交互。譬如,用户下单时,需要获取用户和地址信息,就要调用“用户上下文”;需要获取饭店与菜单信息,就要调用“饭店上下文”。

此外,用户在下单时,是在“下单上下文”提交的,那么如何让饭店及时得到通知,并执行接单呢?就需要“下单上下文”在提交订单的同时,发起一个“下单事件”的通知,通知“接单上下文”提醒饭店及时接单。同样,饭店在餐食准备就绪以后,也会发起一个“就绪事件”,让“派送上下文”及时去通知骑士完成派送。

通过以上的梳理,每个团队就各自完成了各自的领域模型,并确定了自己与其它团队的接口。有了这些准备以后,所有团队就可以坐在一起,召开迭代计划会议了。在SAFe规模化敏捷框架中,管理大师W.爱德华兹.戴明就提出:“如果让系统中的各团队自我管理,各个团队就会自私自利、相互竞争,成为彼此独立的利益中心,从而破坏整个系统的利益。”所以,必须要在各敏捷团队之上,再增加一个“项目群层”的组织机构,站在全局的角度来协调各个团队,让组织的利益最大化。在项目群层中,有产品经理PM、发布火车工程师RTE和架构师ARC,以敏捷发布火车的形式,管理这个项目的多个团队。

为什么需要“项目群层”这样的组织机构呢?就拿在线订餐系统的这个案例来说,整个项目最终的诉求是用最短的时间完成所有的功能,交付客户。然而,这个项目最长最耗时的流程是“用户下单”、“饭店接单”、“骑士派送”的这个流程,只有它们完成了开发,整个项目才算完成。但它们在开发过程中都需要其它团队的接口,而其它团队却把完成自己的工作作为最优先级,把完成别人的接口作为次优先级。这样,虽然其它各个团队都早早地完成了自己的工作,但最核心的这部分功能却被耽搁了。站在整个项目的角度来看,这些核心功能不能完成,其它业务完成得再快,有什么意义呢?所以就需要在更高层次上予以管理和协调。

所以,各个团队都准备好各自的领域模型以后,在产品经理的组织下,让所有的团队在同一时间、同一地点召开一个PI计划会议,来对齐彼此的迭代计划。PI计划会议召开两天,在第一天的时间里,每个团队在各自的看板中制订各自的迭代计划。待办事项中都有哪些用户故事,每个用户故事都有几天的工作量,按照优先级将它们摆放到最近的几个迭代周期中。除了聚焦这些用户故事以外,每个团队还要关注两个东西:任务依赖与潜在风险。

任务依赖就是在描述,为了完成以上这些用户故事,我需要哪些团队给我提供哪些接口,只有提供了这些接口,我才能在迭代结束时完成并交付我的用户故事。在上图中可以看到,用户下单团队向饭店管理团队与用户管理团队都提出了一些接口的需求。潜在风险则是在描述,为了完成以上这些用户故事,我可能会面临哪些潜在风险。这些潜在风险即包括技术方面的、人员方面的,也包括资金方面的、需求不确定等方面的。当第一天结束的时候,各个团队就会将这些任务依赖与潜在风险,由敏捷教练集中交给项目群层进行讨论。

项目群层的产品经理、RTE和架构师,就会收集所有团队提交的任务依赖与潜在风险,将它们放在一起进行综合考虑。首先,他们会将任务依赖交给提供接口的团队,如以上用户下单团队提出的需求,会分别交给饭店管理团队与用户管理团队。接着,产品经理和架构师会综合考虑各个团队提出的风险,提出解决的方案。如以上案例提出的性能需求,就会交给架构师去思考相关的解决方案。

PI计划会议的第二天,各个研发团队会重新制订迭代计划,将其它团队提出的接口需求纳入到迭代计划中。这时候,自身的用户故事与其它团队的接口需求,哪个更加优先级,哪个应当排在前面,哪个应当往后挪?这时候,产品经理、RTE和架构师会在各个团队中转悠,关注各个团队的协作。譬如,某些优先级很高的用户故事,希望研发团队尽快完成,交付客户。这时,产品经理就要关注这些用户故事的依赖任务,其它团队是否优先完成相应的接口,不影响整体的进度。

当一个团队向另一个团队提出接口需求时,他们应该怎样去协作呢?一种思路是接口提供方在上一个迭代中先完成该接口,接口的使用方再在下一个迭代中完成相应的用户故事,交付用户。这种方式虽然比较稳妥,让各方都能够比较从容地应对问题,但这种方式会使得交付延迟,交付速度慢,影响用户满意度。

另一种思路是让接口的提供方与使用方在同一个迭代周期同时开发。当双方协调好接口以后,先由接口提供方编写一个契约测试,然后基于该测试去实现接口,并通过该测试。但提供方在还未完成接口之前,可以先提供给使用方一个“桩程序”,那么使用方就可以使用这个“桩程序”,在不用调用对方接口的情况下正常开发、调试,完成自己的功能。这样,接口的提供方和使用方就可以同时开始彼此的工作,提高工作效率。当接口提供方完成了接口的开发,同时使用方根据“桩程序”完成了用户故事,再通过集成测试完成最终的调试,最后交付产品。

除了依赖任务,产品经理和架构师还会收集所有的潜在风险,站在全局去制订解决方案。譬如本案例中下单团队提出的订单跟踪功能的性能问题,架构师就会提出一个新的方案,成立一个订单跟踪团队去设计一个新的订单跟踪微服务。在这个微服务中,不仅要收集“用户下单”、“饭店接单”、“骑士派送”几个团队的数据,还要通过NoSQL数据库进行存储。因此,学习和选型NoSQL数据库、搭建NoSQL数据库环境也成为任务的一部分,称之为“使能故事(Enabler Story)”。除此之外,还有更多的诸如读写NoSQL数据库、事件通知等技术问题,通过架构师的梳理,交给架构团队将其下沉到平台上,为各团队赋能。

最后,通过以上的梳理,将所有团队及其相互的协作关系,最后绘制到项目群公告板中(如下图)。通过这个公告板就能够清楚地展现有哪些用户故事,需要哪些团队的协作,最后在哪个迭代周期交付,以及这里面重要的依赖与里程碑事件。各个团队就可以按照这样的节奏开发,完成并交付各自的工作。

如果对以上内容感觉有用,欢迎关注、点赞、转发!

(待续)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值