天天看点

《持续交付-发布可靠软件的系统方法》读书分享 

 首先简单对这本书做个介绍。《持续交付》是持续交付这个概念开始广为人知的一步著作,被誉为是2010年最重要的技术书。作者是Jez Humble 和 David Farlery,两人都曾担任过ThoughtWorks 的技术顾问和咨询师,敏捷开发技术的先行者。中文译者桥梁也曾任职ThoughtWorks的咨询师,在敏捷开发方面具有丰富的经验,后来,他自己又写了一本《持续交付2.0》 。持续交付这本书,以怎么样实现构建流水线为核心,串联了很多的行业最佳实践,它们贯穿了一个软件实现的整个生命周期,向我们展示了一个真正的敏捷应该有的样子。

     好了,让我们一起来看书。

《持续交付》分为了三个部分:

第一部分是基础篇,先全景了持续交付想要达成的具体的目标,和实现持续交付过程中的几个重要内容,分别是:配置,持续集成,和测试。

第二部分是部署流水线,叙述了部署流水线的概念和部署流水线上的几个重要阶段应该做什么,怎么做的问题,分别是:构建和部署,提交,自动化验收测试,非功能性测试,以及程序的部署。

第三部分,围绕持续交付中涉及到的外围设施使用和策略问题,给出了相应的最佳实践。他们分别是:基础设施和环境管理,数据管理,组件和依赖管理,以及版本控制。

差异

持续交付带给我的震撼,首先是持续交付的效率。在持续交付第一章,就谈到软件的发布问题,通过分析集中常见的软件的发布的反模式,和持续交付的式做对比,展现出两种方式之间效率上的巨大差异

反模式下,每次发布都是一次祈祷,似乎充斥着运气的成分,经常通宵达旦,筋疲力尽。

持续交付,自动化的发布模式下,所有的工作只是需要点一下鼠标这么简单,发布几乎是再几秒间就完成,没有人感觉到发生了一次发布,这个不就是我们一直希望的事情么?

当然是的,只不过,我们想的和实际之间,缺少了太多的环节和实践,比如测自动化测试,环境验证等。而这些正是构建持续交付这个大的最佳实践的基础,把这些环节串联起来,就是构建流水线。

构建流水线(Build Pipeline)

《持续交付-发布可靠软件的系统方法》读书分享 

                                  图片来源:极客时间《十倍程序员工作法》

《持续交付》对部署流水线是这样定义的:

    对软件从版本控制到用户手中一系列过程的自动化构建过程的建模。在持续集成和发布管理工具上,它体现为支持查看并控制整个流程,包括每次变更从被提交到版本控制库开始,直到通过各类测试和部署,再到发布给用户的过程 。

   在构建流水线中存在多个阶段

《持续交付-发布可靠软件的系统方法》读书分享 

这些阶段是提交阶段、自动化验收阶段、自动化验收、以及后续的各个环境的部署阶段,一个阶段不通过,不允许进入下一个阶段。

这样,通过构建流水线,把一个应用软件从产生到发布的所有相关人员串联到了一起,有关产品和开发人员,有关于测试和运维人员。这个流程是一个自动化的流程,自动化不是说就不需要相关人员的参与,而在于把这些执行过程中复杂且容易出错的环节变成了可以重复自动化的环节。从构建到发布的整个过程,对于所有人都是可见的,这样,发布流程中的低效环节就会很快的反馈出来。

持续交付的目标,是让软件具备随时可以部署到生产环境的能力。显然,保证软件交付的质量,是整个目标的前提。所以,持续交付的核心就是:自动化测试。

自动化测试

说起测试,所谓开发人员的我们很容易觉得:那不是测试应该做的事儿么?一开始我也这么觉得,直到接触到TDD(测试驱动开发)后,才猛然惊醒,自己这份责任推诿了很久。

测试时一个贯穿软件全部生命周期的一个内容,开发阶段的单元测试,组件测试和部署测试,验收极端的功能测试以及非功能测试,部署阶段的部署测试都是测试的内容,作为开发,起码应该打响代码质量保卫战的第一枪。  

最近,我参与《重构,改善既有代码的设计》的中文译者熊节老师办的一个测试驱动开发的训练营,进行了为期一个月的测试驱动开发训练,深刻的感受到了测试对于开发人员的深刻意义。

首先,拿什么来保证你的代码是可靠的?答案就是:测试。Micheal Feathers 在《修改代码的艺术》一书中有句被很多书引用过的名言:遗留代码就是没有测试的代码。这句话把测试对于一个软件系统的质量保障作用的重要性提高到了一个前所未有的高度,每次让人听到都心头为之一震,原来自己的代码从一开始就已经出现了腐化。(末尾我添加了该书的PDF 附件,现在该书已经停版)

《持续交付-发布可靠软件的系统方法》读书分享 

      测试的作用有两个:一方面,构建代码质量的安全网,让开发人员可以放心的对代码进行重构,另一方面,就是快速反馈,可以快速暴露缺陷,有限提高开发人员的开发效率,保证代码的质量。《持续交付》 中提到:“修复那些在提交阶段发现的问题,要比修复那些由后续运行大量测试的阶段发现的问题简单得多。”

   关于测试还有一个常谈的话题:没时间写测试。甚至还有人在知乎上提出过代码质量守恒定律这种无稽之谈。用这种理由拒绝写测试后,我们看到的是另一种怪现象:改bug就像是打地鼠,永远没有结束,直到开发人员崩溃。

   测试会强制开发人员写出可以测试的代码,TDD 的节奏:红-绿-重构,保证代码随时可以通过测试和保证高质量的代码。还有就是在动手写测试之前,必须对开发的所有任务有一个清晰的分解列表,这样,对开发节奏和开发质量,都有一个全局性的指导作用。从整个角度来说:测试代码就是一个可以运行的需求文档,只要有不符合需求的地方,立马可以给出反馈。

   关于验收测试和非功能性测试,涉及到测试人员,今天不多提及。

 版本控制

   版本控制在《持续交付》中也占据了相当大的篇幅,甚至部署环境也被纳入了版本控制的范围。版本控制是持续交付的基石,几乎所有开发相关的资源都被纳入了版本控制,包括源代码,测试代码,文档,配置信息等等。

其他的不多说,对于版本控制,《持续交付》 反复提到一个理念就是:频繁提高代码到主干,保证主干代码上的代码随时都是可以发布的代码,注意三个关键词:频繁,随时,发布。频繁提交,保证主干上的代码随时都是最新的,这个是保证主干代码实时性的前提;随时可以发布,保证代码随时都是可以通过测试的代码,这样,测试的又被放到的眼前,所以,可以测试的代码,是保证代码质量的前提。

由频繁提交,延伸到另一个分支使用策略:使用主干进行开发,这个是行业内的最佳实践,使用主干开发的前提就要求必须能频繁的提交代码,这样,代码每次拉取的代码差异就会小的多,很容易随时进行集成,避免项目后期的“合并地狱”。当然,如果你要说代码质量风格,质量啥的,这都是前提内容,代码风格,质量啥的,都可以用相应的插件来检查,比如checkStyle等,不符合代码格式检测,不符合测试覆盖率要求的代码都是无法提交的。所以,主干上的代码一定是符合要求的,高质量的,可以运行的代码。郑晔老师曾说过:你多久提交一次代码?如果你的回答超过一个上午,对不起,你的步子太大了。

使用主干进行开发的分支策略并不是否定gitFlow 或者pull Request 这种分支策略的使用,关键在于什么时候使用分支。根据书中提建议:尽量避免使用分支策略。除非为了发布或技术调研创建分支,以及在极困难的情况下没有更合适的方式通过别的方法对应用程序做进一步的修改时才创建分支。如果创建了分支,也要保证这个分支的生命周期不会太长,很快就会切回主分支。

下图是书中的一个插图:可以想一下这种分支策略下,合并会是何等苦难的一件事儿。

《持续交付-发布可靠软件的系统方法》读书分享 

如果使用了分支,实现持续集成就成了一件不可能的事情,因为各种合并本来就是一件成本很高的事情,和持续交付的目标南辕北辙了。

    小结

说起持续交付,我开始很容易联想到另一个词语:持续集成,也很容易想到持续集成服务器,例如:Jenkins。实际上,在读完《持续交付》之后,才明白持续交付的环节远远要比持续集成广得多,持续集成只是持续交付这个庞大的目标体系中的一部分。 持续交付,是一种让软件随时可以部署到生产环境的能力,这个是持续交付的目标。如果把软件部署到生产环境的过程也全部自动化,这就上升到了持续部署的这个层面。

持续交付的核心是自动化测试,没有测试,就没有代码质量保障和效率,没有反馈。持续交付,除了体系化了持续交付流水线中的理念和实践外,更然我们从一个宏观的角度来去看待两个被说了很久的字:敏捷,很多人,很多组织都在说自己用的是敏捷,是不是真敏捷,拉出个单子和持续交付中说的这些对一下基本就123很明白了。

 《持续交付》全书一共有15个章节,每个章节都有不同的侧重点,我今天挑了三个:分别是:持续交付流水线,版本控制,以及非常核心的:自动化测试。其他的内容,也建议大家去拜读一下,看看好的的工作状态是什么样子的,注意,我没用理想的工作状态来形容,因为这种状态也是可以实现的。

作为一个开发人员,我始终觉得我们的工作不应该是实在反复加班的恶性循环中度过的,解决之道,一定有,最佳实践给了我们很好的指导思路,重点是,要去实践!!!要找到这个职业应该有的乐趣和成就感。

话外

前段时间,知乎上有一场讨论叫做“中华田园敏捷”,有两个回答可以跟大家分享下:

《持续交付-发布可靠软件的系统方法》读书分享 
《持续交付-发布可靠软件的系统方法》读书分享 
《持续交付-发布可靠软件的系统方法》读书分享 

第二个回答是熊节的回答,我看了之后很服气。确实,当前国内田园敏捷盛行软件开发生态确实有一些外部因素,如第一个回答中的这种风格的领导,但是更多的是开发人员本身,自身的基本功是否过硬,自己的工作效率是否合格的,工作是否是有效的。

    我们当前所处的时代,从来不缺乏各种资料,更不缺乏最佳各种最佳实践,只要想找,就会发现最佳实践这个东西基本是公认的,比如测试驱动开发,这个行业最佳实践,从kent back的《测试驱动开发》 ,到Martin Fowler《重构,改善既有代码的设计》,到今天的《持续交付》以及耳熟能详的《整洁代码之道》,以及文中提及的《修改代码的艺术》 ,它都是最重要的内容之一。

有很多的最佳实践其实诞生已经很多年了,很多的人只是听说过(比如我),但是并未深入的一探究竟,是的,我们都太懒了,懒得思考,懒得学习,习惯于当前已成模式的工作方式。郑晔大佬曾说过:这些最佳实践其实做起来也没那么难,就像是一个开关,拨过去就好了。但是前提是你得动手去拨。