Extract Method(提炼函数)
将长函数或者有统一用途的函数提炼出来,放进一个独立函数中,用函数名解释该函数的用途。
不在于函数行数多少,只要能增加清晰度,就去做
一般情况下分为:无局部变量,有局部变量,局部变量在源函数中有操作。
对局部变量再赋值 ,如:
int a = 1;
int b = a * 1;
===>
int b = getB(a);
每个函数最好只有一个返回值,如果有多个返回值,尝试安排多个函数。
Inline Method(将函数内联化)
- 函数内部代码和函数名称同样清晰易读, 在函数调用点直接插入函数本体,然后移除该函数。
- 手上有一群不合理的函数,将他们合并到一个大函数中,在进行重构拆分。
Inline Temp (将临时变量内联化)
只有一个临时变量,只是被简单表达式赋值了一次,而妨碍了重构手法,则需要将表达式内联化,去掉临时变量
Replace Temp with Query(以查询取代临时变量)
找到只被赋值一次的临时变量,将等号右侧的赋值语句提取为独立函数。
循环:再循环中出现多个临时表量赋值,每个变量拆分出一个独立函数。这样有一个问题,会造成循环重复执行多次,重构中的建议为:确定是否影响性能,如果影响,再将变量都放回去。
tips:将临时表量设置为final,可确定是否只赋值了一次
Introduce Explaining Variable(引入解释性变量)
将复杂表达式用临时变量来表示其用途,类似于Extract Method。
if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0 )
{
// do something
}
=>
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// do something
}
当使用Extract Method花费大量工作量的时候,再考虑使用引入解释变量,优先使用Extract Method。经过引入解释性变量之后,再尝试使用Extract Method将解释性变量去掉。
Split Temporary Variable (剖解临时变量)
临时变量在后面的逻辑中如果没有累加,字符串拼接,写入stream或想集群添加元素,都应该只被赋值一次,一个临时变量表示一个结果。
对于多次给临时变量赋值的逻辑,如果没有上述操作,则单独定义临时变量。
double temp = 2 * (_height + _width);
System.out.println (temp);
temp = _height * _width;
System.out.println (temp);
=>
final double perimeter = 2 * (_height + _width);
System.out.println (perimeter);
final double area = _height * _width;
System.out.println (area);
Remove Assignments to Parameters (移除对参数的赋值动作)
以一个临时变量取代入参参数
int discount (int inputVal, int quantity, int yearToDate) {
if (inputVal > 50) inputVal -= 2;
=>
int discount (int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if (inputVal > 50) result -= 2;
注意区别pass by value 和 pass by reference.本质上pass by reference是按值传递的,只不过这个值要理解为整个对象。
Remove Method with Method Object(以函数对象取代函数)
参数过多时,可以构造一个参数对象,将临时变量和局部变量一一对应保存,
在新class中建立一个构造函数,接收元对象及原函数的所有参数作为参数。
再将逻辑移到参数对象中,紧接着对逻辑做重构就会变得相对简单。
Substitute Algorithm(替换你的算法)
将原算法替换成另一个更清晰的算法,直接更换方法体(method body)。
注意点:确保新旧算法的所有test case结果是否一致。