重构
重构与重写的区别:
- 重构:不是对已有代码的全盘否定,而是对不合理的结构进行调整,对合理的模块进行改动;利用更好的方式,写出更好、更可维护的代码。
- 重写:已有的代码非常庞杂混乱,难以修改,重构还不如重新写一个来得快。根据需求另立一个项目,完全重写
为什么进行重构
常见原因:
- 重复代码太多,没有复用性,难以维护,需要修改时处处都得改
- 代码的结构混乱,注释不清晰,没有人能清楚地理解这段代码的含义
- 程序没有拓展性,遇到新的变化,不能灵活处理
- 对象结构强耦合,业务逻辑太复杂,牵一发而动全身,维护时排查问题非常困难
- 部分模块性能低,随着用户数量的增长,已无法满足响应速度的要求。
什么时机进行重构
重构分为两个级别类型:一是对现有项目进行代码级别的重构;二是对现有的业务进行软件架构的升级和系统的升级。
对于第一种情况,代码的重构应该贯穿于软件的开发过程中。
对于第二种情况,大型的重构最好封闭进行,由专门的(高水平)团队负责,期间不接任何需求,重新设计、开发新的更高可用、高并发的系统,经集成测试通过后,再用新系统逐步替换老系统。
虽然重构可以随时随地进行,但还是需要一些触发点来触发你去做这件事。这些触发点主要有以下几个。
- 添加新功能时。当添加新功能时,如果发现某段代码改起来特别困难,拓展功能特别不灵活,就要重构这部分代码使添加新特性和功能变得更容易
- 修补错误时。在你改Bug或查找定位问题时,发现自己以前写的代码或者别人的代码设计上有缺陷(如扩展性不灵活),或健壮性考虑得不够周全(如漏掉一些该处理的异常),导致程序频繁出现问题,那么此时就是一个比较好的重构时机。
如何重构代码
重命名
懂得都懂
函数重构
- 提炼函数:将大函数(上千行的函数)拆分一个个子函数。重复函数同样提炼成一个函数
- 去除不必要参数:如果函数体不再需要某个参数,果断将该参数去除。尽量不要为未来预留参数(需要用到的时候再加),除非你很确定即将用到它。
- 用对象取代参数
- 查询函数和修改函数分离
- 隐藏函数,如拷贝、删除
重新组织数据
- 用常量名替换常量值
- 用getter 和 setter方法替换直接方法:尽量避免直接访问类的成员属性,可以将类的成员属性声明为private,然后定义public的Getter和Setter方法来访问这些属性。
- 用对象取代数组
使用设计模式改善代码设计
- 把具有相似功能的类归纳在一起,并抽象出一个基类,让这些类继承自这个基类(也称为父类)
- 把子类都使用的方法和属性提炼到父类,并声明为protected(部分方法可能要声明为public)
- 不同体系的类之间(如动物和食物),依赖抽象和接口编程,即依赖倒置原则
代码整洁
- 提炼出一个通用的方法
- 判断放入循环内,减少循环代码
- 枚举类型的判断用 switch…case…
- 减少嵌套的层次,有if判断,对否定条件提前退出,避免箭头型代码