Bob大叔新作。
1. 前言
一直以来的阅读习惯里,都是根据自身需要来查找相应的书籍来进行购买;不过对于Bob大叔的著作,我的个人态度则变更为"无脑买就行,如果感觉看不懂,那就从自身找原因,并且多看几遍"。
是的,正如《架构整洁之道》所介绍的,经历几个关键节点之后,本人就成了Bob大叔的脑残粉,Bob大叔的Clean系列一直深刻影响着我的职业生涯。
2. 全书印象
本书依然延续Bob大叔过往的行文风格:真诚、平易近人、循循善诱、旁征博引(本文底部会对其进行详细解释)。
整体而言,这本书于笔者而言,阅读体验非常好,一来是上面所说的作者深厚的技术底蕴和行文风格,二来本书中的内容也是过往一直有所思考的,阅读过程中时不时豁然开朗的感觉,类似于快速反馈的激励机制刺激着笔者不断读下去。这一点其实也和书中TDD机制下,以秒计周期有着异曲同工之妙。
全书被分为三大部分,分别是纪律、标准、操守。由低纬度到高纬度,由具体到抽象,逐级递增地展现匠艺的高要求,可以看作是职业程序员逐步成长的晋级指南。
3. 全书脉络
3.1 第一章:匠艺
作者专门作为第一章来对"匠艺"进行解释。
本章中,作者对截至目前为止的计算机发展史中的里程碑节点进行了介绍,并以航空业发展史来对比软件发展史,来论证软件研发领域缺乏足够熟练掌握自己所做之事,深刻理解自己技艺的程序员。
本章节的末尾,作者还给出了关于"匠艺"的定义 —— 匠艺是指懂得如何做好某件事。它源自良好的指导和大量的经验,它需要从业者主动去学习那些决定他们记忆水平的纪律、标准与职业操守。
3.2 第一部分:纪律
本部分针对各类程序员,从实用性,技术性和规范性角度阐述纪律对于软件开发的基础性和重要性。
本部分,乃至全书中,作者都在不断强调一个观点:"TDD是系统良好设计,让软件保持soft特性的最好方式"。
基于这个观点为前提,作者整理了TDD三条法则,四项纪律,十五条规则。
-
三条法则。乃是TDD纪律的基础。
红灯 - 绿灯 - 重构
a. 第一法则:在编写因为缺少生产代码而必然会失败的测试之前,绝不编写生产代码。
b. 第二法则:只写刚好导致失败或者通不过编译的测试。编写生产代码来解决失败问题。
c. 第三法则:只写刚好能解决当前测试失败问题的生产代码。测试通过后,立即写其他测试代码。
d. 重构。重构是TDD的第四法则。最终形成如下的循环。
-
四项纪律。
a. 创建测试集,方便重构,并且其可信程度达到系统可部署的水平。即:若测试集通过,系统就可部署。
b. 创建足够解耦、可测试、可重构的代码。
c. 创建极端反馈循环周期,保障代码编写工作以稳定的节奏和产出运行。
d. 创建相互解耦的测试代码和生产代码,以资方便地分别维护,无需在两者之间复制改动。 -
十五条规则。
这里就不再摘抄了。
本部分作者提出"TDD为基础,前提"的观点同时,以一系列代码级别的demo进行讲解如何实践,一步步地向读者展示TDD的优势,以及初学者践行TDD时候可能遇到的问题,同时给出问题的相应解决方案,并且在合适时机穿插相应的业内相关的理论知识。
- 测试集应该和代码一样享受同等级别的设计资源投入,测试是应该在项目起始阶段开始。
- 测试应该做到和代码的解耦,在模块和组件层级之下,代码类与测试类一对一的情况是一种错误思维,这是出现代码稍微有所变动,相应的测试出现大量需要修复的问题,进而导致TDD被放弃的重要原因。
- 测试应该是针对需求验证的单独设计,在模块和组件层级之上,测试的设计反应代码的设计,在这个层级,测试和代码才应该是一一对应的关系。
- 完整的测试集其实就是个有限状态机。它描述了其所要检测的软件是如何由一种状态变为另外一种状态。
-
TDD不确定性原理决定了,测试的确定性和灵活性属于鱼和熊掌的关系,这也是我们必须针对测试做好设计的原因,我们要清楚知道我们所更为看重的,并且在之后的实践中不断提醒团队成员。
image.png
针对本部分作者的TDD介绍,笔者结合个人的思考总结下:
- TDD中所编写的每个测试用例,其实就是描述我们想要的软件(这里是代称,更好的用词应该是SICP中所说的cloud)所要满足的条件之一,当"所有的应该满足的条件"都被验证之后,那么我们所编写而成的这个软件(cloud)就是我们所需要的。不论它是否符合我们最初的设想,是否符合我们的设计理念,是否符合我们过往所养成的常识。既然这个cloud可以让我们所能想到的一系列验证都通过,那么它就是只"鸭子"(借鉴自:在程序设计中的"鸭子类型"概念 —— “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”)。
- TDD极大缩短了程序员编码时的反馈周期,通过这种逐步构建要求(即测试用例)来建立起整个软件的安全防护网,极大增强团队对于代码的信心,使得团队可以放心地对代码甚至架构进行重构,确保了代码质量的下限,也为代码质量的不断提升铸就了坚实的基础。
引申一下:
- TDD所营造的这种以秒计的循环,也是契合了笔者过往数年在公司内部推广DevOps的目标:打造类似快速的研发测试反馈环境,不断加速研发效能。
- TDD其实也对应了一类高效学习方法:先成功(最小可行集),然后在此基础上一点点地验证你的想法,记住是一点点,一旦失败能够马上退回来那种。这样你就始终处于一种连续正反馈的场景之下,极大加速新知识获取的效率。
3.3 第二部分:标准
本部分描述世界对于程序员的期望。 适合于管理者了解对于专业程序员应有的期望。
本部分只有三个章节,但是其所要表达的观点相当犀利。三个章节分别从生产力、质量、勇气三个角度对于标准进行了详细描述。
对于生产力而言:
-
我们需要明确“完成”的概念和定义。本部分作者以测试集来代表对于"完成"的要求,能够通过所有测试的应该就被认定为完成。这在正反两方面为TDD指明了方向:正方向上,我们要所编写的软件能够让测试集全部通过;反方向上,我们也需要确保所编写的测试集应该是完整,准确地反应了软件所有需求。只有这样,才能做到测试通过即可部署上线。
类似观点推广到通常的研发流程里,笔者过去在无数现实面前所思考的 —— 到底何为"完成",研发说完成就是完成了吗?测试说没问题就是完成了?难道不应该是最终客户点头才算是完成吗?基于这个前提,我们应该如何加速这个周期循环,从而打造更高的研发效能? -
我们所需要的是稳定的生产力。Bob在本书的第233页里用不足百行的文字准确解答了笔者的疑惑。笔者在过往面对各种解决问题的讨巧方法时的无力感 —— 你明知道让他们这么搞下去,一定会在未来遭受反噬;但此刻的他们比你更振振有词,导致你甚至开始怀疑是不是自己错了。
对于纪律和标准的无视和倦怠,随着时间流逝,系统对于外界变化的响应越来越慢,研发人员开始将问题归结于系统架构不行,代码太糟糕;不断逼迫管理层,要求从头开始设计系统;最终管理层因为生产力的不断下降被迫接受研发的要求,于是新一轮的循环开始。
现在,看到一位技艺精湛的前辈明确,清晰地说出让自己内心困惑的答案,对于阅读者而言,实在是一件幸事。
对于质量而言:
- 如果我们想要极致质量,那我们就需要持续改进我们的代码;而持续改进代码就意味着我们需要不断修改代码;但如果没有一套可靠的测试集为我们掌舵,我们势必无法完成这项工作;于是我们一定会恐惧和抗拒变更。这种恐惧和抗拒也一定会导致对于代码的修改是按照对程序员安全,而非对系统最好的方式进行的,这势必会加剧系统的不稳定性,造成系统的进一步退化。
- 我们要明确QA的工作。QA的工作应该开始于研发过程的开始处。QA的工作是用测试指定系统行为,给出足够细化的测试,方便排除最终系统中的缺陷。这些测试应该由程序员而不是QA来执行。
3.4 第三部分:职业操守
本部分所描述的内容属于最高追求。以誓言或一套承诺的形式体现编程职业的道德背景。
如医疗领域的希波克拉底誓言,Bob大叔在本部分的开篇提倡了软件开发人员的十条誓言。并用本书的最后三章进行了逐一解释。
十条誓言振聋发聩,涵盖个人职业品质要求,个人发展要求,以及作为团队一员时的要求。
十条誓言所给出的标准相当高,但这并不意味着当下的我们是不合格的,十条誓言是指引我们前进的灯塔,指导我们走在职业程序员道路上时,所需修炼的品行有哪些,所需要追寻的目标在哪里,我们需要穷其一生去不断磨练这些品行,接近这些目标。唯有如此,我们才能称得上拥有匠艺。
本部分同样也提出了一些让人茅塞顿开的理念,给人以豁然开朗的感觉:
- 拆分是人类解决问题时候的惯用手段之一。而细思之下,TDD的红灯 -> 绿灯 -> 重构也就是一种功能分解,因为你需要针对待解决问题的细部来写测试,那么势必需要将功能拆解为可测试的元素。
- 本书以TDD为切入口,并在本部分介绍了SCM(Source Code Management)的发展史,两者的共同点之一就是不断缩短的周期,通过短周期打造出来的快速反馈,让问题尽早暴露,从而降低修复成本。我们不惧怕问题,我们甚至欢迎问题,修复问题能够为我们提供学习的机会,也能够逐步增加我们对于软件的信心,当然这一切的前提是我们有一个可靠的,不断完善的测试集来为我们提供软件状态的实时报告。
- 要想走得快,就要好好走。这是作者在本书的第308页所引用的。看着作者对这句话的解释,回想过往自己这么些年的职业生涯的所见所闻,大量的研发人员甚至不少领导都认为软件研发里,构建/测试/部署耗费不了多少时间;每每向他们解释其中存在的巨大浪费时候,他们总觉得你在故意夸大,哪有这么严重的表情。我们还有很长的路要走,才配得上职业这两个字。
- 预估结果应该是时间范围,概率分布。作者在本部分直接表明,如果你是基于dealline来倒推进行排期,那么这就不是预估;而且没有人能够做到精确的预估,只有实际去做才能够知道确切的完成时间。并且如果想要通过细化拆分需求来精确评估这个时限,所耗费的时间可以认为等同于实际的研发工作。这是管理者所需要明白的,也是专业研发人员所需要传达给管理者的。
3.5 其它一些感触
- 软件应该柔软,是为了让我们可以方便地改变电脑的行为以满足用户的要求,否则不就成了硬件。
这个观点并非是在本书中首次提出,在作者的上一篇作品《架构整洁之道》就已经出现了。
想来也是,我们为了方便地改变电脑行为才创造了软件,结果现实往往是随着维护时间的增长,软件越来越像硬件,看似所有的代码都是我们自己所编写,都是可以更改的,但实际上所有人都像面对抽积木塔游戏的最后阶段一样,每一步都走得胆战心惊。而作为造成这一切的我们,每个人都认为自己也不想这样,自己不应该为这种情况的出现负责。 - 你也有一份职业,你的职业生涯也需要你的照顾和维护,所以请每周大约投入10—20小时给它。
工作对于我们来说是输出,我们正是以此来换取生活物资以延续自身的发展。
如果一个系统只出不进,那么很快这个系统就会被掏空,最终价值归零而被遗弃。我们应该主动向我们的职业生涯中输入新的能量来源,保持它的活力,以谋求平稳发展,以及更高的个人追求。 - 遵守适当纪律,不让工作失控,这将是困难所在。
1947年,计算机祖师爷图灵预见这段总结时,是否能够料到快百年后的今天,人们对于这个问题依然束手无策。
本书所提倡的三大匠艺要求里,纪律也正好是其它两项的目的,不论是标准,还是职业操守,最终都是为了让研发人员能够自觉,主动地遵守标准,改进优化标准,以更好的完成自己的职业所代表的使命。
4. 个人的一些观点
Bob大叔在书中传达的观点和理念,我是完全赞同和认可的,我也曾经练习过TDD,甚至在部门内部小范围内试点,不过在一个传统业务研发公司,这些举措毫无疑问地失败了。
但是,失败并不代表我们没有信仰,没有心中的那块净土。失败也不代表TDD有错,我们的现实选择有错。只能说是TDD不适合业务型研发团队,正如我一直在保持更新的走出软件作坊
系列,传统软件研发团队的痛点,注定了TDD无法被接受。
不过,TDD的形不适合,并不意味着学习它毫无用途。研发团队的整体改良需要高屋建瓴的指导,而TDD的神恰到好处。
我无法推进TDD的落地,但它蕴含的思路能够让你能够感知到,整艘船是否行驶在正确的路上,偏离了多少,这条路途上是否存在致命礁石。
5. 补充 - Bob大叔的灯塔作用
上面谈到Bob大叔著作中展示的“真诚、平易近人、循循善诱、旁征博引”,这里详细解释下。
5.1 真诚。
这是Bob大叔的著作里最吸引笔者的原因。Bob大叔在本书中依然会以自己过往职业生涯中的错误作为反例来向读者证明他所陈述的内容是从实践中一步步思考总结而来的,并且他也在书中不断明确地向读者传达自身也是在不断犯错中慢慢成长起来的,读者不应该为自己的犯错或胆怯过多自责。
保持住一颗不断追求卓越的心,在实际的工作中不断优化自己的代码,做到这样你就已经是一个优秀的程序员,这是Bob大叔在他的一系列Clean系列书籍中不断地,明确地告诉读者的。可以说笔者能够最终跳出"犯错 --> 被问责 --> 自我怀疑 --> 畏首畏尾 --> 犯错 --> ..."的怪圈,Bob大叔的书籍确实在那段黑暗的时光里给了我很大的力量。
Bob大叔不仅坦诚地告诉读者自己也遇到过类似的问题,而且会还详细描述自己的犯错经历以及其间的心理状态和反思过程,并在最终总结出一些"心灵鸡汤"口号 —— 这些口号放在平时总会让我们起逆反和厌恶的心理,但在目睹了一个让人尊敬的前辈如此坦诚地描述自己过往的失败经历以及相应心路历程之后,这些口号反而成为了我们走好未来职业生涯的指路灯。
未来的职业道路上你可能会再次陷入迷茫,想起这些口号,想起这些口号背后的故事,从而获得新的内心力量坚持下去。你过往习得的理论知识和规范与你现实场景下看到的有着非常大的偏差,这并不代表这些前辈们的经验和教训总结出来的理论知识和规范是错误的,理论和规范代表的是长远,而现实环境里很多表现都是基于短期利益做出的抉择,如果不能坚定信念,那么当事人很容易被环境影响而放弃曾经的理想,陷入迷茫,认为"学那么多基础理论和规范有个屁用,最后不还是CRUD仔"。
同样的话在不同人口中说出来,说服力是完全不一样的。Bob大叔的渊博学识和赫赫声望让我们可以笃定我们过往所习得的理论和规范,这些诸多前辈努力成果的结晶不会是错误的,那么现实里所观察到的为什么恰恰相反呢? 这就需要教员的《实践论》和《矛盾论》来指导了,既然理论没错,那难道是现实错了?但如果仅仅是"现实错了"这一句话就回答所有的问题,那如何解释你所看到的这个错误现实在过往持续了多年,并且依然未显露出衰亡的迹象?
面对这样的矛盾中,如果不能够坚定理论正确性的信念,那么早晚会陷入“这个可能是理论有问题,那个可能是我们的实践有问题”的反复中,而这样的左右摇摆会导致我们失去对于理论的信心,失去对于现实改造的决心,最终让人产生放弃的念头。
Bob大叔的真诚让我们坚信他所介绍的理论是经过其自身反复实践认证,并且多方大牛认可,我们只需要去探索为什么我们的现实与前辈们的教诲不一致,找到原因,向前辈们看齐。
5.2 平易近人,循循善诱。
本书中,对于想要表明的观点,Bob大叔依然是以研发人员最熟悉的代码层面作为切入口,亦步亦趋地演示如何通过TDD是如何推动我们的研发进度的,并且为此做了专门的视频。不仅仅告诉读者目标是什么,而且全程演示如何一步步地达到目标,包括其中走过的弯路,也一并呈现。
5.3. 旁征博引。
Bob大叔悠长的职业生涯,渊博知识量,以及显赫声望,于是书中频繁引用行业内其它大牛言论来佐证自己的观点,甚至会描述他自己和这些人的交流讨论,以及针对某些观点告诉读者他已经在自己的其它Clean系列著作中有详细描述, 这种交叉验证在优化了阅读体验之外,也极大给与读者信心 :
- 首先是作者观点的一致性,这说明这些观点是作者多年思考总结沉淀下来的,能够历经这么多年考验,说明一定值得反复理解和思考;
- 还有就是既然这些观点是被诸多大牛交流过的,而且作者作为亲历者,这些观点被曲解传达的可能性不大,那这些观点就是能够经受住考验的,习之则利大于弊。
网友评论