修改软件的艺术:构建易维护代码的9条最佳实践
[美]David Scott Bernstein
这本书旨在帮助你降低构建与维护软件的成本。给出一些最佳实践的方法。我可以直接在摘要将这9条建议列出来,但是有一些很精妙的话、很切实的感受还是需要自己通过阅读书本去获得。读完这本书会让我对“软件开发工程师”这个职业产生一种自豪感和满足感,为自己是这个行业中的一员表示很庆幸。要知道在此之前我为自己只是单纯的“crud”有点被磨平了热情,但是现在又找回了初心,希望这本书也能为你带来一些不同以往的观点,刷新你的认知。
文中有两个观点讲的很不错,一个是测试驱动开发的红绿重构,一个是开发的工作是使软件持续产生价值,其实更重要是对于这本书题目的刻画–“构建易维护代码”。在谈构建易维护代码之前,我们应该问问自己,为什么要构建易维护的代码?做这件事的意义是什么?不做会有什么风险?其实我在读完之后对“软件价值”有了比较深的理解,软件也像生命一样,是有周期有寿命的,总有结束的那一天,我们开发人员就像医生一样,要做的事是尽量的延长“软件”的寿命,使其产生持续的价值。那怎样延长它的有效周期呢?就需要在coding的时候遵守这些实践准则,构建易维护、易拓展、可重用的高质量代码,使其发挥最大的功效,产生最大的价值。这就是保证代码质量的意义。同时书中有提到一个方法帮助你去多思考,就是多问问why,为什么要这么做?这也是我在不断被问的过程中逐渐意识到的,有这种why的意识很重要,这种业务逻辑是怎么考量的?技术选型为什么是这样的?换成别的行不行?其实我们做任何事的时候都是一个不断抉择的过程,为什么要选这个,多问问自己理由。为什么我要写读书总结?为什么我要读这本书?asking is the true word.answering is the key world。ß
九个最佳实践
(1)在问如何做之前先问做什么、为什么做、给谁做
(2)小批次构建
(3)持续集成
(4)协作
(5)编写整洁的代码
(6)测试先行
(7)用测试描述行为
(8)最后实现设计
(9)重构遗留代码
软件是纯粹的思想产物。它源自我们的大脑,通过我们的手指,输入到计算机中。而它掌控着一切。
如果软件有人用,那么它便需要被修改;所以必须编写出可修改的软件。
为了要对某些事物准确建模,我们必须先理解它。
成为一个出色开发者需要的所有条件都是可以学习的技能。
与其试图预计将来可能的修改,我们应该研究出一些工程实践帮助软件更好地应对修改。
软件开发面对着不同于其他学科的独有挑战,为了应对这些挑战,我们必须理解这些实践背后的原则。
工具越强大,也越容易误用。
用链锯伐木比手锯更快,同样也更容易伤到自己。这个物理世界的隐喻在虚拟世界同样适用。工具越强大,也就越容易误用,所以我们必须小心使用手中的工具,才能保证它正确发挥作用。
谈软件行业:需要学习、实践和分享
所以这行需要不停的学习,新技术层出不穷,每出一样又多了一个全新的知识点,可以探索一个新的领域,新的方向,岂不美哉?出现一个山头,征服一座山。哪个行业会像我们这行这么磅礴,这么生机勃勃啊?
软件一直处在未知世界之中,技术、原则和理论在不断进化,这种状态将会一直持续。软件开发是一个年轻的行业,即便我们发展迅速,也依旧前路漫漫。
对此没有简单的答案,但可以用我们的才智来解决这些问题。让我们开始公开讨论和共享标准,敞开心扉珍视那些重要的事情。
最终,构建一个健康的行业,就像构建一个健康的社会一样,需要每个人都参与其中。任何组织都是依靠其成员运作的,我们已经见到以前所未有的方式进行软件开发的新型组织正在崭露头角。开源、知识共享协议,以及诸如GitHub8 这样的工具,给各种工具和库提供了免费获取渠道。我们有了改变整个行业的基础。剩下的只是愿不愿意使用的问题。而且这种转变正在发生着。
从软件开发行业来说,需要分享的精神。正如医学界一样,科学界一样,技术需要分享,才能促进行业的进步,社会的进步。
一所医院的医生如果将能够救人一命的信息对其他医院的医生保密,那是不道德的。软件开发者也是一样。我们开发的一些产品真的会挽救生命,所以我们必须分享知识。如果我们提高了整个行业的专业性,就会得到正反馈。我们分享方法论、模式、原则、实践。我们并不需要分享商业机密和专有信息。
学习、实践、分享。
我们需要分享那些可学习且容易理解的原则和实践,这样才能为软件开发建立规范——为了让它成为真正的专业性行业。
这和其他工程领域的道理一样。经验丰富的水电工都遵循着久经考验的标准和实践,而确立这些标准和实践的人们不单是以最快、最高效地完成工作为目的。他们也在考量其他因素,比如公共安全。他们必须合理接入市政供水和排水系统以及电网,而且这些标准必须是通用且可执行的。
谈软件工程师
其实,程序员就是一个翻译家,把人需要去做的事情,翻译成语言,让计算机去做。那在翻译的过程中确实会存在着一些误差,这个误差,就是我们说的bug,bug是一定会存在的。没有完美的翻译家,也没有完美的程序员。问题是如何快速的定位bug修复bug下次避免再发生类似bug,才是职业程序员的腻害所在。在这个成长的过程中,有很多tips可以帮助我们成为更好的程序员。在意细节,追求产出价值的同时保持代码的优雅,岂不是很棒?
我们都是凡人,总会犯些小错。但是在严格按照指令执行的计算机中,一个小错误可能引发大问题。计算机不知你的真正意图是什么。它们不是传译或者翻译,又或者仅仅将代码当作建议或指导,而是盲目地执行特定的指令。所以,如果遵循特定的规范保证程序正确执行,然后持续进行测试,我们就可以(通常是非常快速地)修复任何bug然后继续工作。耽误不了多少时间。
谈软件开发工作
其实实质是:程序员打代码是工作中的小小一部分而已,更多的是沟通、对接、写文档,更更重要的,是找bug,定位问题。找bug、捋顺代码逻辑,是很占工作时长的。如果你发现一个问题,随手有一个测试用例可以测该功能函数,不用找测试入参、不用看代码细节、不用找函数返回结构,一个test run起来,都明了了。
有人会告诉你实践TDD能减少缺陷,但是有成本。你会编写比产品代码两倍还多的测试代码,所以自然而然人们会认为这降低了开发速度,但这是个错误的假设。这种想法认为影响软件开发速度的瓶颈因素是打字。
但这不是真的。询问任何一个开发者,考察任何一个项目。开发者花费的大部分时间不是在编码上,而是在以下方面:阅读需求文档、编写文档、开会,还有最耗费时间的排查bug。
这句话总结了极限编程的要点。
极限编程中的开发实践,诸如测试先行、重构、结对编程、设计技巧和持续集成,是软件开发成功的关键,无论采用哪种开发方法论都是如此。它们对理解问题域和精确建模提供了环境。
谈重构
如何选择是否需要重构
如果生产环境上的软件正常工作不需要扩展,则无需重构代码。重构代码有风险和成本,所以我们希望最后收益能够抵得上开销。
第二次做好
相反,试图一蹴而就会有很大的压力。对于所有人来说都一样。知道可以回过头去修改、随时清理(可以在任何时候重构),会让我们很自由。
重构的开闭原则
重构是在不改变外部行为的前提下调整设计。开闭原则是指软件实体应该“对扩展开放而对修改关闭”。换句话说,力求在添加新功能的时候做到添加新代码并将现有代码的修改最小化。避免修改现有代码是因为很可能会引发新的bug。
如果有天发现倒车档失灵,你会在这种无法倒车的情况下开多久再去检修变速器呢?
有些事情最好放到最后处理,有些则不能推后。知道这两者之间的差别绝对重要。代码也是一样。有缺陷的bug要及时补丁,不然就从一个点漏成一条缝、一个洞了。
他们没法倒车,所以必须调整他们的行为(驾驶习惯),绕弯路到达目的地,为的是不使用倒车。一个问题会导致更多的问题。越早处理技术债,花费的成本就越低,就像信用卡欠款一样。
为什么要做重构?程序员也需要学习说话的艺术之道。
他看着我问道:“那你为什么要重构?”
我应该如何回答?
软件开发者时常遇到这样的情况。有时候不知如何作答,是因为我们和管理层存在沟通障碍。我们使用的是开发者的语言。
我不能告诉经理重构代码是为了好玩,是因为它让我感觉良好,或者因为我想要学习Clojure或者其他新技术……这些对管理者来说都是不可接受的答案。我必须强调重构对于公司的重要意义,而且它确实意义重大。
开发者知道这些,但需要用恰当的词汇也就是商务用语来表达,其实就是收益和风险。
我们如何在降低风险的同时提高收益?
软件本身的特点决定了其高风险和多变性。重构能降低以下四个方面的成本:
·日后对代码的理解
·添加单元测试
·容纳新功能
·日后的重构
重构的定义
<