为了定位一个bug花掉一整天的时间,修复了一个bug又衍生出了新的bug,打开一段项目源代码,完全不知所云,随着新增需求,项目越来越难以维护,这些都是代码需要重构的信号。
一、重构是什么
对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
二、如何重构
1.何时重构
一般情况下,不会有集中的一段时间来重构,可以在开发新功能,修复bug的过程中做重构。如果采用了TDD的方式(测试驱动开发),那重构已完全融入到开发过程中,如果没有采用TDD方式,可以参考一下几种情况,来确认是不是要重构:
- 如果有一部分代码出现多次需要修改,说明这部分代码在很大概率上以后还会要修改,那么这部分代码就需要重构。
- 当添加修功能时,我们可以做些重构的工作。
- 在修复bug时,如果大部分时间话在bug定位上,那多半是因为代码结构不清晰,如果代码在同一抽象层次上,每个方法都在10行以内,每个方法名和变量名都能清晰的表达意图,那么bug就无处藏身。
- Code Review时,汇集每个程序员的修改意见,等Code Review结束后开始重构。
2.何时停止
- 通过所有测试
- 没有重复
- 清楚表达意图
- 最少程序元素(类、接口、方法、变量)
- 代码整洁
3.重构策略
可以采用“测试保护,小步重构”的策略方式。通过加一个端到端测试以保证不破坏重要的功能,如果实在很难编写测试代码,也要手工测试保证重构真的没有改变软件行为;使用版本控制系统,小步提交,保证随时可以放弃变更,回到上次满意的状态。
4.重构过程
- 测试保护,添加测试代码,测试代码跑通,审查测试代码,看是否有遗漏一些场景。
- 找出需要重构代码,这个和我们的代码审美相关,没有一个统一的标准,如多大的类算过大的类,多少行代码算是过多;这方面会随着我们的编码经验而形成,还有更快的方式就是阅读大量开源的优秀代码,参见《重构》一书。
- 重构方法,参见《重构》一书。
- 测试验证。
三、重构和设计
开始无需用很多设计模式将系统搞的很复杂,先用简单的方式满足当前需求,待需要重构时再调整设计。只要最终代码能保证满足需求,高效稳定,代码整洁,易于维护,管他符合哪种设计模式呢。
四、大型系统的重构
首先要对代码分类:
- 不会被执行的代码
- 运行稳定,基本不会改动的烂代码
- 经常出bug的烂代码
- 经常需要变更的烂代码
不会被执行的代码,直接删除就好了。运行稳定的又不需要改动的,动它反而可能引入风险,当然,在时间充裕的情况下,还是可以重构的。真正有价值,值得重构的,投入产出比最高的,是经常出问题和经常会有需求变更的烂代码。优化了这部分代码,可以减少 Bug 和进行需求变更的时间。