第一章 重构,第一个案例
- 编译器不会在乎代码好不好看,都是正常运行的。但人在乎,差劲的系统很难修改,因为很难找到修改点,导致程序员很有可能犯错,从而引入bug
重构的第一步
- 得为即将修改的代码建立一组可靠的测试环境
- 让测试有能力自我校验,否则就得耗费大量时间来回对比,降低重构开发速度
- 好的测试会为程序员提供必要的安全保障
分解并重组
- 代码块越小,代码的功能就越容易管理,代码的处理和移动也就越轻松
- 找出代码的逻辑泥团并运用提取方法
- 找到函数内的局部变量和参数
- 每次修改的幅度小,所以任何错误都很容易发现,不必耗费大量时间进行调试
- 可以改变变量名称,好的代码能够清除表达出自己的功能,变量名称是代码清晰的关键
- 任何一个"傻瓜"都能写出计算机可以理解的代码,唯有写出人类容易理解的代码才是优秀的程序员
- 临时变量只在自己所属的函数中有限,所以它们会助长冗长而复杂的函数
- 重构大半时间都是用来弄清楚代码所做的事
- 最好不要在另一个对象的属性基础上运用switch语句,否则需要把该对象属性作为参数传进去
- 也有另一种方法,用多态来取代switch语句
总结
- 所有的重构行为都使责任的分配更合理,代码的维护更惺忪。重构后的程序风格,更偏向于过程化风格
- 重构的节奏:测试、小修改、测试、小修改…,的节奏才能让重构得以快速而安全地前进
第二章 重构原则
何为重构
- 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本
- 使用一系列重构手法, 在不改变软件可观察行为的前提下,调整其结构
- 重构技术,提供了一种更高效且受控的代码整理技术
- 重构使软件更容易被理解和修改;重构不会改变软件可观察的行为
为何重构
- 重构改进软件设计
- 当人们只为短期目的,或是在完全理解整体设计之前,贸然修改代码,程序会逐渐失去自己的结构,程序员越来越难通过阅读代码而理解原来的设计
- 代码结构的流失是累计性的
- 重构像是在整理代码,让所有东西(代码)回到应处的位置上
- 完成同样一件事,设计不良的程序往往需要更多代码,改进的一个重要方向就是消除重复代码
- 重构使软件更容易理解
- 让你的代码变得“准确说出我所要的”
- 重构帮助找到bug
- 重构能够帮助程序员更有效地写出强健的代码
- 重构提高编程速度
- 重构帮助你更快速地开发程序
- 良好设计师维持软件开发速度的根本,重构可以帮助你更快速地开发软件,因为它阻止系统腐败变质,甚至可以提高设计质量
何时重构
三次法则
- 添加功能时重构
- 能够帮助我理解需要修改的代码
- 在前进过程中把代码结构理清,可以从中理解更多东西
- 重构的另一个原动力:代码的设计无法帮助我轻松添加我所需要的特性
- 修补错误时重构
- 调试过程中运用重构,多半是为了让代码更具可读性
- 复审代码时重构
- 代码复审,有助于在开发团队中传播知识,也有助于让较有经验的开发者把经验传递给比较欠缺的人,并帮助更多人理解大型软件系统中的更多部分
- 程序员希望程序更容易阅读,所有逻辑都只在唯一地点制定,新的改动不会危及现有行为,尽可能简单表达条件逻辑
- 重构是这样一个过程:他在一个目前可运行的程序上进行,在不改变程序行为的前提下使其具备上述美好性质,使我们能够继续保持高速开发,从而增加程序的价值
重构的难题
- 数据库
- 绝大多数商用程序都与它们背后的数据库结构紧密耦合在一起
- 重构后的数据迁移,过程十分漫长且繁琐
- 解决方案:
- 在对象模型和数据库模型之间插入一个分隔层,隔离两个模型各自的变化
- 修改接口
- 如果接口被修改了,任何事情都有可能发生变化变化
- 如果重构手法改变了已发布接口,必须同时维护新旧两个接口,直到旧接口彻底被没人用
- 难以通过重构手法完成的设计改动
- 先想象重构的情况
- 何时不该重抽
- 重构之前,代码必须起码能够在大部分情况下正常运作
- 项目非常接近最后期限时不该重构
重构与设计
- 重构肩负一项特殊使命:它和设计彼此互补
- 写代码前,可以先做预先设计,但不一定是最正确的解决方案,能够得到一个足够合理的解决方案即可。在后续的开发过程中,不断改进当前的解决方案,从而想最佳方案的方向前进
重构与性能
- 在短期看来,重构的确可能使软件变慢,但它使优化阶段的软件性能调整更容易,最终还是会得到好的效果