一、根本
1、在不改变软件可观察行为前提下改善其内部结构,使程序更容易被理解和修改,但对用户是不变
2、有时候只是移动一个字段或者或者提炼函数,或者在继承体系中推上推下
3、重构是什么、为什么要重构、哪里该重构、怎么重构
二、初探
1、重复的代码如果不抽出来会导致以后修改得多方修改
2、需要设置好测试的程序,能进行自我检测更快定位问题
3、局部变量和参数:不会被改变的可以当成参数传入其他函数,只有一个变量修改的可以当成函数的返回值
三、重构时机
1、重复代码:提取代码,若互为兄弟考虑提取到父类,若无关系可考虑建立第三个类供引用
2、过长函数:小函数带来解释、共享、选择能力,分解函数,取好函数名,独立功能/条件/循环可抽
3、过大的类:太多实例变量,考虑建立新类供使用
4、过长参数列/多处出现的变量:采用类的属性
5、发散和霰弹变化:一个类受多种变化影响,一种变化影响多个类--考虑分类
6、依恋情结:取值调用了第三个类大半的函数,考虑把这些调用语句抽到独立函数
7、基本数据偏执:可考虑多用对象,比如集合数值和币种的money
8、switch:使用多态代替
9、消息链过度耦合:提取函数
10、父类应该只留存子类共用的部分
四、重构测试
1、保证有单元测试和功能测试,好测试的程序,能进行自我检测更快定位问题
五、重构手法
函数类
1、提炼函数(Extract Method)
动机:函数过长
做法:创建新的子函数用意图来命名
范例:
- 无局部变量:直接抽取
- 有局部变量:传入参数
- 局部变量再赋值:作为返回值
2、以查询取代临时变量(Replace Temp with Query)
动机:只有一次赋值的变量多次被引用
做法:引用变量的地方改成函数调用
3、解释性变量(Introduce Expaining Variable)
动机:if 等表达式条件过长
做法:每一项作为一个final 的表达式
范例:
4、分解临时变量(Split Temporary Variable)
动机:非循环非结果的变量被赋值两次
做法:每次赋值创建独立的变量
范例:
5、移除对参数的赋值(Remove Assignments to Parameters)
动机:对一个参数赋值
做法:临时变量代替参数
范例:
6、以函数对象代替函数(Replace Method with Method Object)
动机:局部变量过多导致无法提取函数
做法:局部变量变成对象属性
7、替换算法(Substitute Algorithm)
动机:替换某一算法
范例:
对象类
1、搬移函数(Move Method)
动机:函数被另一个类使用更多
做法:移到使用多的类
2、搬移字段(Move Field)
动机:字段被另一个类使用更多
做法:移到使用多的类
3、提炼类(Extract Class)
动机:一个类做了两个类的事(比如用户中的地址相关信息)
做法:部分字段移到新类
4、隐藏委托关系(Hide Delegate)
动机:需要用委托类调用另一对象
做法:隐藏内部工作原理,统一入口建立委托函数(如果建立过多委托则不可以)
范例:
5、引入外加函数(Introduce Foreign Method)
范例:
数据
1、对象代替数据值(Replace Data Value with Object)
动机:某数据项跟其他一起使用才有意义
做法:数据项变对象
范例:订单中的用户用对象而不是用一个字符串
2、值对象改为引用对象(Change Value to Reference)
动机:值对象进行再分类
做法:值变引用对象
3、复制被监视数据(Duplicate Observed Data)
动机:ui和业务耦合
做法:Observer模式,分层
4、 常量替代不变数字(Replace Magic Number with Symbolic Constant)
范例:
4、 常量替代不变数字(Replace Magic Number with Symbolic Constant)
范例:
表达式
1、分解条件表达式(Decompose Conditional)
范例:
2、合并条件表达式(Consolidate Conditional Expression)
范例:
3、合并重复片段(Consolidate Duplicate Conditional Fragments)
范例:
4、取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses)
范例:
函数调用
1、函数带参(Parameterize Method)
范例:
2、保持对象完整(Preserve Whole Object)
范例:
3、引入参数对象(Introduce parameter Object)
范例:
概况关系
1、字段上移(Pull up Field)/ 函数上移(Pull up Method)/ 构造函数上移
范例:
2、提炼接口(Extract Interface)
范例:
3、模板函数(Form Template Method)
范例: