重构 refacting
在不改变代码外在行为的前提下,对代码内部结构进行修改。是一种代码的整理方法,本质上就是在代码写好之后改进设计。
每一次修改,完成之后都要进行测试,因而在重构之前,准备一套较为信赖的测试数据,以保证重构的正确性很重要
提高代码的可修改性,降低修改成本,提高阅读性
营地法则
编程时,保证离开时的代码库比来时更加健康
两个帽子
使用重构技术开发软件时,我把自己的时间分配给两种截然不同的行为:添加新功能和重构。
添加新功能时,我不应该修改既有代码,只管添加新功能。通过添加测试并让测试正常运行,我可以衡量自己的工作进度。
重构时我就不能再添加功能,只管调整代码的结构。此时我不应该添加任何测试(除非发现有先前遗漏的东西),只在绝对必要(用以处理接口变化)时才修改测试。
为何重构
重构改进软件的设计
代码长时间不重构,代码慢慢积累,结构越来越不明显,最终程序的阅读性越来越低,维护起来更加困难。经常性的重构代码,有助于维护代码该有的形态。
像编程中出现的重复代码,在处理自己的逻辑时,可能因为其他重复的地方忘记修改导致失败,因此消除重复代码,就可以确认事务跟行为在代码中出现在一处。
重构使软件更加容易理解
程序设计很大程度是与计算机交流,告诉计算机自己需要做什么,但是源码除外计算机一个读者外,还有别的读者(开发者)。自己在开发时,只负责实现功能,不顾程序的可阅读性,会使后来者理解起来更费力,因此自己重构代码,让后人更容易理解,设计的关键。
重构帮助寻找 bug
结构清晰,代码容易理解,解决 bug 自然更加轻松。
重构能帮助我更有效的写出健壮的代码
重构提高编程速度
在没有重构的代码上开发功能时,阅读理解代码则会花费大量时间,
而在具有良好结构的程序上开发,可以很清楚的看到在哪里开发,在哪里修改,及时引入bug,也可以很快发现
何时重构
三次原则:Don Roberts 给了我一条准则:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构
预备性重构:让添加新功能更容易
重构的最佳时机就是在添加新功能之前。
就如同在开车去某个地方时,得看地图选择最优的路线,而不是朝着一个方向走到底
帮助理解的重构:使代码更易懂
在理解一段代码时,全靠记忆可能会忘记,但是通过重构,可以将理解代码对应起来,通过允许重构的代码,看理解的是否正确
捡垃圾式重构
在自己开发功能的时候,发现有代码可以重构时,可以选择去重构这一部分,在不影响自己开发进度的情况下,挑着想重构的部分进行重构,慢慢积累重构
有计划的重构和见机行事的重构
上面的 预备性重构、帮助理解的重构、捡垃圾式的重构 都是见机行事的重构,可能都是在添加新功能的时候进行重构,并没有安排特定的时间去重构
肮脏的代码需要重构,但漂亮的代码也需要很多重构
长期重构
代码重构可能花费的时间不一,在面对复杂的代码时,重构可能花费更多时间,像这些代码就是重构区,添加新功能时要是靠近到重构区,则可以主动去向改进的方向靠近
复审代码时重构
重构的挑战
延缓新功能的开发
重构的唯一目的是让我们开发更快,用更少量的工作量创造更大的价值
代码所有权
就以一个接口为例,接口开发者和接口调用者可能所属不同团队,作为接口开发者的一员,在重构接口时,可能会涉及到修改接口名称,但对于接口调用方来说,咱并没有权力去修改,这种就会阻塞重构
分支
不用开发在开发代码时都会有自己的分支,在频繁的将自己的分支代码合到主分支的过程中,
测试
重构结束,保证程序的行为特征不变,这才是最终目的,但是,人总会犯错,重构的过程就会不可避免的就会产生问题
遗留代码
遗留的代码往往是最复杂,最麻烦,
数据库
数据库重构
重构与性能
一些重构方法,不可避免的会对程序性能造成影响,但是,对于重构后的程序,性能优化起来也更加的容易
除了对性能有严格要求的实时系统,其他任何情况下“编写快速软件”的秘密就是:先写出可调优的软件,然后调优它以求获得足够的速度。
3种编写快速软件的三种方法:
1、时间预算法
最严格的方法,一般用于对性能要求极高的实时系统。分解自己的设计时需要对每个组件所需要的时间包括空间这些资源进行分配,提前预算好,
2、持续关注法
要求任何程序员在任何时间做任何事时,都要设法保持系统的高性能。
关于性能,一件很有趣的事情是:如果你对大多数程序进行分析,就会发现它把大半时间都耗费在一小半代码身上。如果你一视同仁地优化所有代码,**90%**的优化工作都是白费劲的,因为被你优化的代码大多很少被执行。你花时间做优化是为了让程序运行更快,但如果因为缺乏对程序的清楚认识而花费时间,那些时间就都被浪费掉了
3. 依据上述 90% 的统计数据
在对代码进行重构时,并不关注性能,而在进入性能调优阶段,再遵循特定的流程进行调优
流程:
首先应该有一个工具来监控程序的运行,可以更清楚的了解程序哪些地方消耗大量的时间与空间,方便去找到性能热点所在的那一小段代码
然后就可以持续关注这段代码,采用持续关注法中的优化办法进行调优
重构名录
重构的记录格式
重构手法的五个部分:
- 重构方法的名称 (name),可能会有别名
- 简单的速写(sketch),帮助自己更快的选择需要的重构方法
- 动机(motivation),介绍为什么重构已经什么时候重构
- 做法(mechanics),简明扼要的一步步介绍怎么进行重构
- 范例(examples),用一个例子说明该重构方法怎么运行