软件开发中,多人协作是一个常见的场景,如何来协作管理不同开发人员开发的代码变成重中之重,因此 CVS 等版本管理工具也应运而生。现如今,Git 已经占据了版本管理的主导地位。基于版本控制出现了一系列的开发模式,用以帮助团队更加快速地协作。本文中,作者从他的实践,全面的展示了主干开发的模式在开发中应用的优势,希望能给你的工作带来更高的效率。
以下为译文:
写在前面
这是我「流行软件开发实践」系列文章中的第三部分,在本系列文章中,我计划包含软件工程师通过提升开发流程和实践来改善软件开发的一系列方法。我曾在 ThoughtWorks 担任软件顾问,现在我在德国一家大型的零售公司工作,这些方法都是我在职业生涯中学习并实践验证过的。
在我的职业生涯中,我一直在做一件事,倡导着能让开发团队提效的实践,当然,我也花了很多时间去尝试这些实践。
在这些实践中,有一个是我非常喜欢的主题,主干开发 (TBD)。有意思的是,和测试驱动开发一样,它也受到了很多高级软件开发者的反对。
在软件开发过程中,有很多刻板印象,并且很多软件开发者深受其害。而主干开发的思想直接与那些刻板印象直接开战,这也是我喜欢它的原因。
在外人看来,IT 行业中的软件开发者就像是 “神话中的人物” 一样,这些开发者们头带着耳机,用 3 到 4 个显示器,他们的显示器上永远是黑色的窗口,并跳动着绿色的字符,当他们接到一个任务时,会在一个暗黑的环境下,很快的完成任务,做到一般人想都不敢想的事情。在几年前,只有 19 岁 Rumor,花了一周时间编写了 2048 游戏,仅两周时间就有超过 1 亿用户[1]。就是这些事件,让很多人都觉得开发者无所不能。
这些程序员的故事在大众之中流传,给程序员带上了光环,虽然,这些光环让程序员很酷。但是,这些光环只会给团队在软件开发上带来负面影响。
如果团队中存在带着光环的程序员,那这种基于主干开发的形式基本不能被实现。基于主干开发的模式需要团队合作,团队人员都要有同理心、并且开放。所以,在团队中最好不要有个人主义很强的人,那样子极不利于协作。
什么是基于主干开发?
基于主干开发(TBD)是一个软件开发的流程,trunkbaseddevelopment.com (网站中有非常多关于 TBD 的资料)网站中有如下定义:
在版本控制的分支模型中,开发人员都在同一个被称为“主干“的分支中进行协作,多个开发人员的代码的汇聚在一起,从而避免创建长时间无法合并分支。因此,这种方式避免了合并地狱,也不会破坏构建,并从此让开发人员过上幸福的生活。
这个观点强调,我们不应该为新的功能创建分支,也不要让代码在分支中开发完成后才合并到主干上。我们应该把新功能拆分出很多小的块来实现,并且在每一块完成的时候都将它推送到主干中去。
换句话说,项目组成员在开发的过程中,不应该使用任何分支。
我知道,对于任何一个工作过一段时间的开发者来说,将代码”直接推到主干“都是非常激进的做法,都会不由自主的抵制 TBD 的想法。但是我希望,你能继续往下看,我会在本文中,尽我所能,解决你的疑问。
为什么 TBD 重要?
我不得不再次提到敏捷开发中定义的衡量软件开发有四个关键指标,因为他们真的很重要。在书中,这样写道:
我们研究过在成功技术改造中都具有的实践,他们包含版本控制,自动化部署,持续集成,主干开发以及低耦合架构。
这些实践不仅仅是重要,而是必须。之前,我写过关于持续集成的文章,基于主干开发也是其中的一部分。
基于主干开发中,除了可以让提交代码块变小,减少合并冲突,它还能在以下几个方面有较大提升:
部署频率和故障平均恢复时间
TBD 与 CI/CD 进行配合使用,完成功能的代码都会经过测试,这些测试为”绿色“的代码会被发布到生产环境上。每一个更改都推送到主分支上,这意味着会有大量的集成和部署。在我的团队里面,每天大概会发布 30~40 次。提高部署频率是敏捷开发四个关键指标中的第二个。
我记得曾经在我的团队发生过这样子的事情,有一个”用来展示属性列表“的简单的前端页面,我们把这个页面发布上线,但是在代码中缺少了 Null 和 undefined 的检查,最后导致前端出现了错误。
当然,这种错误的出现与使用哪种开发模式并没有关系。但是,如果使用主干开发,我们可以在 5 分钟内编写测试并修复这个 Bug,并将新的版本发布到生产环境中。平均故障恢复时间是敏捷开发四个关键指标中的第三个。
这种基于主干开发的模式,与 CI/CD 结合,能够快速帮助团队发现问题,并在处理问题时使用”前滚“的方式,而不是”回滚“。
代码质量与知识共享
在 TBD 的模式中,代码会被直接提交到主干上,通常情况下,大多数人都会觉得,这样子做,代码库中的代码质量会受到影响,并且错误的可能性也会上升。我的观点与之相反,TBD 不仅可以提高代码质量,也能使程序的鲁棒性更强。
我们来看下面这个场景,团队中使用分支开发,并且使用 pull-request 的方法来进行代码合并。当功能开发完成时,开发人员需要发起一个 pull-request 请求。而团队中的其他人员需要查看并评论另一个开发人员花费数小时完成的代码,这是一个多么痛苦的过程,并且不一定能发现其中的问题。
但对于 TBD 来说,因为没有了分支,也就意味着没有 pull-request,也不需要安排高级开发人员进行代码审核。对于大多数团队来说,只要遵循”四眼原则“就行了,即至少有两个开发人员查看并批准代码进行入主分支。
我的团队中,我们使用结对编程的方式来实现”四眼原则“,一切都运行良好。在 TBD 中,没有了 pull-request, 结对编程变得很有必要。两个开发人员一起解决问题比一个开发人员单独工作时要好很多。每个开发人员都有不同的技术栈和不同程度的经验,结对编程也可以让开发者向队友学习。
想像一下,当一个初级工程师与一个高级工程师协作时,团队的代码规范能够在最短的时间进行传递,代码设计也可以在开发初期被纠正,而不是在开发完成后在进行反馈。两人一起写代码,也标识着他们都知道代码是如何运行的。
协同
结对编程是团队协作中的一种模式。TBD 的模式在团队协作中,能提高团队成员的同理心,让团队成员更好的协作在一起。
对于一个在行业中从业多年的开发者来说,在没有看到代码之前,就将一个新手写的代码合到主干上,这是一件非常有挑战的事情。但是作为队友,我们要相信我们的伙伴,在没有别人帮助时,也能够胜任相应的工作。对一个团队来说,信任非常的重要。
高级工程师都很聪明并且大多数都有丰富的经验,但是,你要相信,团队其它人也是非常聪明的。你可以让经验丰富的程序员评审新手的代码,提升代码的质量。当然,你也可以使用结对编程的方式,并且过不了多久,你就会发现,即使是新手,也能写出非常优秀的代码。
潜在的挑战
没有完成的新功能
没有人愿意将没有完成的新功能(如一个没有实现功能的按钮)发布到生产环境中给用户使用。为了解决这个问题,我们可以使用新功能开关[2],在新功能没有开发完成之前,这个开关一直保持关闭,这些新的功能将会被隐藏。当新功能开发完成,测试通过后,在将开关打开或者将开关移除。不仅如此,还可以使用这个开关来做 A/B 测试。
测试与监控
主干开发需要团队有一个很强的测试套件,并且有一个好的监控器,能够在出现错误的时候,及时通知到开发人员。越快的反馈循环越好。CI/CD 中阻塞的问题需要第一时间处理,防止其它成员获取有问题的代码,影响他们的开发。
为了防止这种阻塞的问题,我们可以将代码功能拆分成尽可能小的提交,并且尽可能使你的开发环境与与测试、生产环境类似,并且在每一次提交之前,都运行一下那些管道任务。
我知道,已经有很多团队,如文中所述一样,实现了基于主干开发的模式,这些团队都没有在切回原来的 Pull Request 的模式。还有一些团队是因为其它原因,切换到主干开发的模式,例如团队需要使用结对编程。
软件开发和生活一样,同一件事情并不一定适合所有的人。最重要的是,我们要找到适合自己团队的模式。我曾经就遇到过这样子一个例子,团队中的人数为基数,这就表示他们没有办法在所有任务上都分配两个人进行结对开发,这导致他们在任务分配上”心力交瘁“。在这种情况下,他们采用分支开发,并每天合并一次,另人吃惊的是,这和主干开发非常类似。
下一步,尝试基于主干开发,并按照你们团队的情况,进行调整,找到最适合你们团队的模式。
引用:
[1]https://www.cnbc.com/2014/03/26/19-year-old-makes-viral-game-hit-in-a-weekend.html
[2]https://martinfowler.com/articles/feature-toggles.html
原文:https://levelup.gitconnected.com/why-are-so-many-people-against-trunk-based-development-a785d9322584
本文为 CSDN 翻译,转载请注明来源出处。
☞还不知道 AWS 是什么?这 11 个重点带你认识 AWS !