懂了这个道理,人月神话不再是神话!

本文书接上回《解决DDD最大难题-如何划分领域》,关注公众号(老肖想当外语大佬)获取信息:

  1. 最新文章更新;

  2. DDD框架源码(.NET、Java双平台);

  3. 加群畅聊,建模分析、技术交流;

  4. 视频和直播在B站。

声明: 本文观点限定在重业务的软件系统研发场景下,其它场景不作为本文讨论的范围。

前言

1975 年《人月神话:软件项目管理之道》首次出版,揭示了一个被程序员奉为圣典的法则,认为增加开发者无法线性地缩短软件交付时间,其中的损耗巨大。时隔近50年,我的软件交付经验中却出现了打破这个法则的现象,我被这些现象深深地震撼,但当时却没有联想到“人月神话”,而最近在思考“如何为大家呈现我们实践DDD所获得的收益”时,灵光乍现,意识到实际上我们已经实现了通过增加人数来有效地缩短项目交付周期的能力,我意识到我们真的打破了“人月神话”。

还是那个故事

我在《为了落地DDD,我是这样“PUA”大家的》一文中,讲述了一支团队落地DDD的实践经历,这里有一个小插曲,在我们重构系统最艰难的时刻,也就是最复杂的订单模块整个生命周期时,我们的进度压力很大,团队期望能够进行渐进式交付,一块一块地交付测试,而订单的“创建-扣库存-支付成功”一整个逻辑又相互牵扯,需要完整实现才能提交测试,评估下来,如果这一块由一个开发者来开发,需要大约三天时间,而我们期望一天能够完成,于是我们本能地想到了方法:“加人”。但我们也很清楚,按照以往地经验,加人的损耗肯定是非常巨大的,三个开发者参与进来,一天能够完成也几乎是不可能的,但我们没有别的选择。

于是,我把三位开发者叫到会议室,按照我们的DDD工作流,花了近一个小时时间,确认了“领域模型”、“创建订单命令”、“订单创建成功事件”、“订单支付成功事件”、各个“事件处理器”逻辑、前端接口定义等设计方案,然后分工分别负责“命令处理器”、“事件处理器”、“前端接口”的开发工作。

令人惊奇的是,基于这样的分工,团队很快完成了各自的工作,并在当天下班前,团队完成了代码合并和联调,意外的进度给我们带来了一丝丝惊喜,但很快投入到了后续的工作中,并没有来得及深入思考。

而此后,团队的交付过程中,类似对于突发事件的应对,也多次复现了这样的现象,似乎我们的分工可以做到更细的颗粒度,使得团队能够通过增加人数的方式缩短需求的交付。

为什么可以这样

在我们团队重新审视这一现象时,我们可以看到:

  1. 我们将交付过程明确分为了“建模设计”和“代码编写”两个阶段,其中“代码编写”需要的能力是模式化、可复制的

  2. 我们的代码组织方式,非常有利于分工;

“建模设计”和“代码编写”

“建模设计”,是输入需求信息,输出方案的过程,是一个做决定的过程,这个过程,本质上是将“不确定性”尽可能转变为“确定性”的结论,需要需求方、决策者建立共识,做出设计结论,这个阶段无法通过加人来加速,但同时也不需要大量广泛的参与者,本质上是由“决策者”参与即可。

懂了这个道理,人月神话不再是神话!懂了这个道理,人月神话不再是神话!

一旦我们“建模设计方案”确定了,而“代码编写”要做的就是按照“模型设计”编写确定性的代码,这个过程本质上就是“做执行”,团队成员一旦适应了团队的代码风格和模式,基本不需要太多的思考,就可以写出“符合预期”的代码,因为这个“预期”已经被“建模设计”框定了。而且实践中我们发现,对于一个新人,通过不到一周的学习和模仿,就可以掌握这个能力。

懂了这个道理,人月神话不再是神话!懂了这个道理,人月神话不再是神话!

所以我们开发团队的整个流程就变成了“做决策”和“做执行”两件事,也是由“不确定性”到“确定性”的快速收敛的一个过程。

懂了这个道理,人月神话不再是神话!懂了这个道理,人月神话不再是神话!

代码风格的可协作性

我在《DDD建模后写代码的正确姿势(Java、dotnet双平台)》一文中为大家展示了我们的代码组织方式,我在视频《掌握这个模型你就能设计一切》(https://www.bilibili.com/video/BV114421Q7vp) 中也介绍过业务系统中,最核心的就是“命令-事件”,系统的所有业务,都可以映射到这个模型中。用DDD+CQRS+Event Driven的组合,我们发现代码被一个个的“CommandHandler”、“EventHandler”拆分成一个个的独立的业务逻辑处理单元,这些单元的协作,在我们“建模设计”阶段已经确定下来,因此,开发者要做的就是完成这一个个填空,就完成了代码的编写,心智负担非常小。

懂了这个道理,人月神话不再是神话!懂了这个道理,人月神话不再是神话!

我们分工的最小颗粒度,就是这一个个的“CommandHandler”和“EventHandler”,这比传统的CRUD按模块分工的颗粒度要细致地多,也就意味着,我们团队可以更细粒度地调配人力,这其中的损耗却几乎可以忽略不记。

我们甚至规定,“当你写代码不舒服时,大概率是建模设计出了问题”,要求开发者反馈并由设计者及时修改迭代模型设计,尽可能地确保开发时,代码的上下文能够获取到支撑实现逻辑单元目标的信息,从而使得整个开发过程是丝滑的。

回到主题

在我们实践DDD的过程中,我们意识到,在“代码编写”环节,我们可以非常灵活地调配人力资源,哪怕是被临时调入项目的开发人员,也可以高效地按照设计完成代码的编写,这其中的损耗几乎可以忽略不记。

基于这样的情况,我们认为,一支研发团队,就可以实现一个建模设计师加上多个实现开发者这样的模型,而这个团队模型,我相信也是很多团队期望的但又很难把协作效率提升上来。

现在看来,我们的实践做到了,所以,我想,人月神话不再是神话。

发表评论

相关文章