关注技术,听从Bob大叔的教导
敏捷爽畅之道中的一星级团队是创造商业价值,特点是团队要转换思维,从用户角度考虑问题;二星级团队是紧跟市场节奏进行产品交付,特点是各类技术实践需要做到位,加强团队的工程实践能力。试点项目已经进入到第2个月,C++和Java技术教练都已经进驻了一段时间,团队加大了在技术实践上的关注和投入。
之前从厚厚的一摞书中选择本周要读的书,想着让自己轻松点吧,就选一本最薄的《The Clean Coder》,没想到这薄薄的170页的书其实很有深度。TW教练给的教练成长计划中,技术实践部分的书籍列表如下:
红框中的3本都是Bob大叔写的,《Clean Code》是一星级,《ASD》是二星级,《The Clean Coder》是三星级,为什么呢?书评中有如下一段可以说明:
“毫无疑问,Bob大叔的这本新作又一次抬高了专业程序员的门槛。在书中,他从交互管理、时间管理、压力管理、合作方法以及工具选择等诸多方面,阐述了他对一名专业程序员的期望。Bon并不囿于对TDD和ATDD的传授,他不仅解释了每一名自视为专业人士的程序员所需要知道的东西,而且指出了他们在历练尚浅的软件开发职业生涯中需要不断精进的内容。”
这个书评和我的阅读感觉相同,这本书中反复强调的是程序员的专业精神和职业素养,感觉要求真的很高,需要持续不断的付出努力才有可能达到,我自己在做程序员的日子中差得很远,我很想说“臣妾做不到啊”。不过如果很容易就能达到的话,这件事情就不值得追求了。从书中Bob大叔叙述的自己40多年的成长经历来看,他也是从菜鸟起步的,犯过很多的错误,不断从错误中学习和成长,所以应该要有信心。
本周读了70页书,在读完了“测试驱动开发”这一章后,迫不及待的想把读后感写出来。
前言 从“挑战者”号爆炸引出专业精神
前言部分讲述了“挑战者”号爆炸的事故,事故原因是由于一个橡胶密封圈在低温下变得僵硬失去弹性,而工程人员在发射前已经认识到并且明确提示了这个风险,要求中止发射,但是管理层可能是因为承担着财务和政治压力,没有采纳工程师的意见,造成了悲剧和巨大的损失。
工程师已经展现了他们的专业精神,但这是否足够了?提出反对发射意见的工程师会不会因为没有坚持自己的意见,采取更进一步行动(比如通知媒体)来避免风险而感到懊悔和自责?
这本书主要阐述软件开发者的专业精神。书中包含了很多实务性的意见,试图回答诸如以下的问题:
1. 什么是软件专业人士?
2. 软件专业人士如何行事?
3. 软件专业人士如何处理冲突,应对很紧的工期,如何和不讲道理的管理人员打交道?
4. 软件专业人士何时应该说“不”?怎么说?
5. 软件专业人士如何应对压力?
你还会发现,在本书的实务性意见背后,隐隐体现出一种奋力突破的积极态度。这种态度提倡要诚信,要富有荣誉感、自尊心和自豪感,要勇于承担作为一名手艺人和工程师所肩负的重大责任。这种责任包括要努力工作,出色完成任务;要擅于沟通,能够就事论事;要管理好时间,能够坦然面对艰难的“风险回报”决策。
除此之外,这种责任之中还包括神圣的使命感。身为一名工程师,你比任何管理者可能都了解得透彻。了解这些也意味着你肩负着要敢于行动的重大责任。
专业精神的关键词:责任。
必读引言
这部分讲述了Bob大叔自己几十年的程序员经历,让大家了解到他并不是一开始就像现在这样NB的。作者强调这部分的重要性,我想主要的目的在于让读者产生继续努力的信心。
我也是程序员。我编了42年的程序。这42年里,我什么都经历过。我被开除过,也被表扬过。我当过小组长,当过主管,也当过普通员工,甚至当过CEO。我的同事有聪明绝顶的,也有混日子的懒鬼。我曾经开发过尖端的嵌入式软硬件系统,也写过寻常公司的工资系统。
具体的结果是引出专业人士的态度、原则、行动,就不再重复了。
第1章 专业主义
“专业主义”有很深的含义,它不但象征着荣誉与骄傲,而且明确意味着责任与义务。这两者密切相关,因为从你无法负责的事情上不可能获得荣誉与骄傲。
如果你不小心放过了某个模块里的一个bug,以致公司损失了1万美元,结果将会怎样呢?非专业人士会耸耸肩说:“难免要出点状况嘛。”然后像没事儿人一样继续写其他模块。而专业人士会自己为公司的那一万美元买单。
哇,自掏腰包?那可真让人心疼唉!但专业人士就必须这么做。实际上,专业主义的精髓就在于讲公司利益视同个人利益。看到了吧,“专业主义”就意味着担当责任。
这一开始的内容就把我惊到了。对于我们做的企业软件,大部分故障的损失都不是程序员自己能够承担的,不过我想Bob的意思并不在于是否真正要自掏腰包为公司承担损失,而是强调要为自己的行为负责。想起一个古老的盖茨和通用汽车总裁关于汽车设计的对话,大致意思是盖茨说如果微软来造车,成本和燃油消耗都会大幅度下降,通用汽车总裁回应说,如果微软造车,车子将会像Windows一样故障高发,极为不安全。确实那个时代Windows蓝屏是很常见的问题,需要重启,但是没有人能接受汽车在行驶中突然熄火再重新打火。软件行业是非常年轻的,远不如汽车行业成熟,需要更多有专业主义精神能够为自己的行为主动负责的工程师。做不到为错误买单,至少要做到不贰过。
这一章作者记录了一个他经历过的报告未能按时生成的故障,涉及到历史代码,排查了很久。根源在于修改时漏过了相应的测试。我们的系统也发生过多次类似的故障,某个定时任务没能按时完成并生成预期的文件,导致对端系统受到重大影响。也许相比直接费用损失类的故障,这个严重程度要低一些,但也会造成很大的影响和客户投诉。内心认为这种故障优先级不高的想法完全不是专业的行为。
Bob大叔给出的最终解决之道汇聚到自动化测试上来,终极解决方案是TDD。以他自己的作品FitNesse为例:
我是开源项目FitNesse的主要贡献者和代码提交者。在写作本书的时候,FitNesse的代码有6万多行。在这6万行代码中有2000多个单元测试,超过2.6万行。Emma的报告显示,这2000多个测试对代码的覆盖率约为90%。
如何创建灵活可维护的软件结构呢?原则和模式这些是很重要,但还有一条实在是没几个开发人员会认真照做,那就是:
如果你希望自己的软件灵活可变,那就应该时常修改它!
这完全与大多数人对软件的理解相反,他们认为对上线运行的软件不断地做修改是危险的。错!让软件保持固定不变才是危险的!
无情重构,童子军军规,话题回到重构和测试上来。
职业道德部分,是关于程序员自己的时间管理的。建议平均每天花3小时时间提升自己的专业能力水平。
你应该计划每周工作60小时。前40小时是给雇主的,后20小时是给自己的。在这剩余的20小时里,你应该看书、练习、学习,或者做其他能提升职业能力的事情。
没时间?
做个简单的计算吧。一周有168小时,给你的雇主40小时,为自己的职业发展留20小时,剩下的108小时再留56小时给睡眠,那么还剩52小时可做其他的事情呢。
或许你不愿那么勤勉。没问题。只是那样的话你也不能自视为专业人士了,因为所谓“术业有专攻”那也是需要投入时间去追求的。
这种计算方法和TED中一个讲时间管理的演讲完全相同,“没时间”的意思其实是“这不在我的优先级列表中”。
Bob大叔提出了我们这个领域的很多知识,不过我确实都不知道,说明我离专业人士还差得很远,不过已经指明了方向,加油吧。
你知道什么是N-S(Nassi-Schneiderman)图表吗?如果不知道,那为什么不了解一下呢?你知道“米利型”(Mealy)和“摩尔型”(Moore)这两种状态机的差别吗?你应该知道的。你能不需查阅算法手册就写出一个快速排序程序吗?你知道“变换分析”(Transform Analysis)这个术语的意思吗?你知道如何用数据流图进行功能分解吗?你知道“临时传递数据”(Tramp Data)的意思吗?你听说过“耦合性”(Conascence)吗?什么是Parnas表呢?
这部分给出了一些具体的学习方向和练习方法,很有价值。
第2章 说“不”
这一章主要讲专业的程序员如何对不合理的要求有策略的说“不”,涉及到团队协作,其中涉及的隐含意思是质量不能妥协,为了进度牺牲质量的事情是不允许的,这会显得很不专业。这个道理其实大家都知道,但是具体如何做呢?看Bob大叔给出的具体案例吧,很有参考价值,可以尝试。不过我觉得这比只是自己努力就能达成的目标难度要更高一些了。
第3章 说“是”
这一章是关于做出承诺。我发现自己经常承诺的事情做不到,包括对别人的和对自己的,所以后续要更慎重的承诺,少说话,少承诺,答应了就一定要做到。
做出承诺,包含三个步骤。
(1)口头上说自己将会去做。
(2)心里认真对待做出的承诺。
(3)真正付诸行动。
识别真正承诺的诀窍在于,要去搜寻与下列相似的语句:我将在……之前……(例如,我将在周二之前完成这个任务。)
这句话的关键在哪里呢?你对自己将会做某件事做了清晰的事实陈述,而且还明确说明了完成期限。那不是指别人,而是说的自己。你谈的是自己回去做的一项行动,而且,你不是可能去做,或是可能做到,而是必须做到。
需要避免的是“我试试”,“我努力”,这些都不是承诺。
专业人士不需要对所有请求都回答“是”。不过,它们应该努力寻找创新的方法,尽可能做到有求必应。当专业人士给出肯定回答时,它们会使用正式的承诺,以确保各方能明白无误地理解承诺的内容。
第4章 编码
对编码的要求:
(1)首先,代码必须能够正常工作。
(2)代码必须能够帮你解决客户提出的问题。
(3)代码必须要能和现有系统结合得天衣无缝。
(4)其他程序员必须能读懂你的代码。
如果感到疲劳或者心烦意乱,千万不要编码。我最糟糕的代码,是在凌晨3点写出来的。
流态区
这一段的意思是心流状态对编码不利,要避免进入流态区。这个见解和我的认知不一致,应该也和大多数人的想法不一致。Bob大叔给出的原因是在心流状态理性思考的能力会下降。
让我说得更清楚些。在流态区,你可能可以敲出更多的代码。如果你当时正在做TDD,你会更快速地重复“红/绿/重构”循环。你会收获一种愉悦感或征服感。问题在于,在流态区状态下,你其实放弃了顾及全局,因此,你很可能会做出一些后来不得不推倒重来的决策。在流态区写代码可能会快些,但是后面你将不得不更多地回头重新审视这些代码。
回想下之前的经历,可能确实如此。心流状态很可能是一种自嗨的状态,只见树木不见森林,会引入一些问题。那怎么解决呢?结对编程。
结对编程最大的一个好处在于,结对中的任一方都不可能进入流态区。流态区是一种与世隔绝的状态,而结对要求持续密切地进行沟通。事实上,我经常听到关于结对编程的抱怨便是,结对会阻碍人们进入流态区。很好!流态区正是要避免进入的状态。
这一段也刷新了我对结对编程的认识。
调试
调试时间和编码时间是一样昂贵的,因此,如果我们能够做些事情避免甚或消除调试活动,那是最为理想不过的。
Bob大叔采用TDD方式将自己的调试时间缩短到以前的十分之一。
不管是否采纳TDD或其他一些同等效果的实践(备注:我不知道有比TDD更为有效的实践了,但是也许你知道),衡量你是否是一名专业人士的一个重要方面,便是看你是否能将调试时间尽量降到最低。绝对的零调试时间是一个理想化的目标,无法达到,但要将之作为努力方向。
很明显这里的备注亮了,专业人士应该TDD,专业人士应该TDD,专业人士应该TDD!原因不多说了,网上搜索下有很多。我想起来上次DDD实战课程上我和“教授”结对,教授开始不愿意先写测试用例,我接过键盘编写用例时发现一个接口函数设计上的问题,让教授开始信服TDD的作用。
保持节奏
这部分不多说了,其实是关于精力管理的。专业人员应该能够妥善管理自己的精力,避免透支。最近我给自己定下规矩,每天晚上12点前必须睡觉,但有时做事情一高兴起来就不愿意遵守这个纪律了。这个应该是和前面说的避免进入流态区可以呼应起来的。
第5章 测试驱动开发
Bob大叔开始对TDD也是拒绝和怀疑的,于是专门找Kent Beck切磋了下,终于完全信服了。要知道那时他已经有三十多年的开发经验。我一直认为TDD这件事情业界还在争论中,Bob大叔以自己的经验斩钉截铁的说:
此事已有定论
此事已有定论!
争论已经结束。
GOTO是有害的。
TDD确实可行。
如果连所有代码是否都可以正常运行都不知道,还算什么专业人士?如果每次修改代码后没有测试,如何能够知道所有代码可以正常运行?如果缺乏极高覆盖率的自动化单元测试,如何能够做到每次修改代码后都对代码进行测试?如果不采用TDD,如何能够获得极高覆盖率的自动化单元测试?
这一系列排比的反问句排山倒海,确实没有办法拒绝。我能想到的唯一可行的回答是:质量并不那么重要,只要软件基本能跑就行。是的,很多时候大家嘴上说质量最重要,但是行动中并未体现出这一点。如果能够真实的用语言说出质量不重要,那就已经不是专业人士之间的讨论了。就酱,无需再多说了。
本章后续的内容很简短,关于TDD本身是什么,以及它的诸多优点,资料已经很多了。感觉Bob大叔这一章的主旨就是停止争论,所以这一章描述得很简洁。
TDD的局限
尽管TDD有诸多优点,但是它既非宗教信仰,也非魔力公式。即使做到了测试先行,仍有可能写出糟糕的代码。没错,因为写出的测试代码可能就很糟糕。
另外,在某些场合按照这三项法则去做会显得不切合实际或不合适。这种情况很少,但确实存在。如果遵循某项法则会弊大于利,专业的开发人员就当然不会选用它。
这最后的忠告很有用,测试代码的质量不高确实也是正在发生的事情,务必要把测试代码当成一等公民看待。
我是有底线的
网友评论