本书写作于1999年;十年后,各种主要的java IDE都提供了良好的重构支持。
1 第1-4章
当自己需要为程序添加新特性,而代码结构使你无法很方便地达成目的,那就先重构那个程序,使特性的添加容易进行。
节奏:测试、小修改、测试、小修改。重构是以微小的步伐修改程序,修改后立刻编译并测试;写出人类容易理解的代码,才是优秀程序员;需要撰写注释时,尝试重构让所有注释都变得多余;重构花的时间并不多,大半是用来弄清楚代码所做的事。
重构是对软件内部结构的一种调整,在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
重构的目的
- 改进软件设计。代码结构的流失是累积性的,经常性的重构可以帮助代码维持自己该有的形态。
- 使软件更容易理解。“准确说出我想要的”,“擦掉窗户上的污垢,使你看的更远”。
- 帮助找到bug。“我不是个伟大的程序员,我只是个有一些优秀习惯的好程序员”。
- 提高编程速度。良好的设计是快速开发的根本。
第一次做某件事时只管去做,第二次做类似的事会产生反感,但还是可以去做;第三次再做类似的事,就应该重构。
重构的时机
- 添加功能。“如果用某种方式来设计,添加特性会简单得多”。
- 修补错误。代码还不够清晰——没有清晰到让你能一眼看出bug。
- 复审代码。最好是一个复审者搭配一个原作者:提出修改建议,共同判断,一起着手修改。
程序有两面价值:“今天可以为你做什么”“明天可以为你做什么”。系统当下的行为,只是整个故事的一部分,如果没有认清这一点,你无法长期从事编程工作。重构就是一条摆脱困境的道路,发现昨天的决定不适合今天的情况,那么放心改变;明天回头看今天的理解也许觉得幼稚,那时还可以改变你的理解。
重构的类型
- 重复代码/Duplicated Code
- 过长函数/Long Method
- 过大的类/Large Class
- 过长参数列/Long Parameter List
- 发散式变化/Divergent Change、散弹式修改/Shotgun Surgery
……
确保所有测试都自动化,检查自己的测试结果;一套测试就是一个bug侦测器,能大大缩减查找bug所需要的时间;频繁地运行测试,每当收到bug报告请先写一个单元测试来暴露bug;添加更多测试,好过对完美测试的无尽等待;考虑可能出错的边界条件,把测试火力集中在那里。测试代码和产品代码有个区别:你可以放心地复制、编辑测试代码,用来处理多种组合情况以及面对多个可供选择的类。