重构注意事项
一、重构的理由
- 1、代码重复;
- 2、子程序太长;
- 3、循环太长或嵌套太深;
- 4、类的内聚性太差;
- 5、类的接口的抽象层次不一致;
- 6、参数表中参数太多;
- 7、类的内部修改往往局限于某个部分;
- 8、需要对多个类进行修改;
- 9、对继承体系的并行修改;
- 10、需要对多个case语句进行并行修改;
- 11、相关的数据项只是被放在一起,没有组织到类中;
- 12、成员函数更多地使用了其他类的功能,而非自身类的;
- 13、过于依赖基本数据类型;
- 14、一个类不做什么事;
- 15、一连串传递流浪数据的子程序;
- 16、中间人对象什么也不干;
- 17、某个类同其他类关系过于密切;
- 18、子程序的命名太差;
- 19、数据成员被设置为公用;
- 20、派生类仅仅使用了基类的一小部分成员函数;
- 21、用注释掩饰拙劣的代码;
- 22、使用了全局变量;
- 23、在子程序调用前使用设置代码,调用后使用收尾代码;
- 24、程序包含的某些代码似乎在将来某个时候才会被用到。
二、数据级的重构
- 1、用具名常量代替神秘数值;
- 2、使变量的名字更清晰且传递更多信息;
- 3、将表达式内联化;[中间变量换成给它赋值的那个表达式本身]
- 4、用函数来代替表达式;
- 5、引入中间变量;
- 6、用多个单一用途变量代替某个多用途变量;
- 7、在局部用途中使用局部变量而不是传递参数;
- 8、将基础数据类型转化为类;
- 9、将一组类型码转化为类或枚举类型;
- 10、将一组类型码转换为一个基类及其相应派生类;
- 11、将数组转换为对象;
- 12、把群集封装起来;
- 13、用数据类来代替传统记录.
三、语句级的重构
- 1、分解布尔表达式;
- 2、将复杂布尔表达式转换成命名准确的布尔函数;
- 3、合并条件语句不同部分中的重复代码片段;
- 4、使用break和return而不是循环控制变量;
- 5、在嵌套的if-then-else语句中一旦知道答案就立即返回,而不是去赋一个返回值;
- 6、用多态来代替条件语句(尤其是重复的case语句);
- 7、创建和使用null对象而不是去检测空值.
四、子程序级重构
- 1、提取子程序或者方法;
- 2、将子程序的代码内联化;
- 3、将冗长的子程序转换为类;
- 4、用简单算法替代复杂算法;
- 5、增加参数;
- 6、删除参数;
- 7、将查询操作从修改操作中独立出来;
- 8、合并相似的子程序,通过参数来区分他们的功能;
- 9、将行为取决于参数的子程序拆分开来;
- 10、传递整个对象而不是特定成员;
- 11、传递特定成员而非整个对象;
- 12、包装向下转型的操作.
五、类实现的重构
- 1、将值对象转化为引用对象;
- 2、将引用对象转化为值对象;
- 3、用数据初始化代替虚函数;
- 4、改变成员函数或成员数据的位置;
- 5、将特殊代码提取为派生类;
- 6、将相似的代码结合起来放置到基类中.
六、类接口的重构
- 1、将成员函数放到另一个类中;
- 2、将一个类变成两个;
- 3、删除类;
- 4、去除委托关系;
- 5、去掉中间人;
- 6、用委托代替继承;
- 7、用继承代替委托;
- 8、引入外部的成员函数;
- 9、引入扩展类;
- 10、对暴露在外的成员变量进行封装;
- 11、对不能修改的类成员,删除相关的Set成员函数;
- 12、隐藏那些不会在类之外被用到的成员函数;
- 13、封装不使用的成员函数;
- 14、合并那些实现非常类似的基类和派生类.
七、系统级重构
- 1、为无法控制的数据创建明确的索引原;
- 2、将单向的类联系改为双向的类联系;
- 3、将双向的类联系改为单向的类联系;
- 4、用Factory Method模式而不是简单地构造函数;
- 5、用异常取代错误处理代码,或者做相反方向的变换.
八、重构的策略
- 1、在增加子程序时进行重构;
- 2、在添加类的时候进行重构;
- 3、在修补缺陷的时候进行重构;
- 4、关注易于出错的模块;
- 5、关注高度复杂的模块;
- 6、在维护环境下,改善你手中正在处理的代码;
- 7、定义清楚干净代码和拙劣代码之间的边界,然后尝试把代码移过这条边界.
PS:我们应当忘记那些琐屑的效率提升,因为在97%的场合下,不成熟的优化乃万恶之源。
重构讲究步步为营,小步前行,可进可退。