03. 重构-重新组织函数

一 Extract Method (提炼函数)

       当看见一个过长的函数或者一段需要注释才能让人理解用途的代码,需要将这段代码放进一个独立函数中。提炼函数有如下好处:

       1 首先,如果每个函数的粒度都很小,name函数被复用的机会就很大;

       2 其次,这样做会使得高层函数读起来就像一系列注释;

       3 最后,如果函数都是细粒度,那么函数的覆写也会更容易一些。

二 Inline Method (内联函数)

       如果函数的内容和起函数名称同样清晰,可以直接使用内部的代码,去掉这个函数。 一些组织不合理的函数,可以将函数都内联到一个大型函数中,再从中提炼出组织合理的小型函数。代码示例如下:

代码片段 A:

int getRating() {
    return (moreThanFiveLateDeliveries()) ? 2:1;
}

boolean moreThanFiveLateDeliveries() {
    return _numberOfLateDeliveries > 5;
}

代码片段 B:

int getRating() {
    return _numberOfLateDeliveries > 5 ? 2:1;
}

将代码片段 A 修改成代码片段 B,清晰易读。

三 Inline Temp (内联临时变量)

       如果有一个临时变量,只是被一个简单表达式赋值一次,而它妨碍了其他重构手法。将所有对该变量的引用动作,替换为对它赋值的那个表达式自身。代码示例如下:

代码片段 A:

double basePrice = anOrder.basePrice();
return (basePrice > 1000);

代码片段 B: 

return (anOrder.basePrice() > 1000);

四 Replace Temp with Query (以查询取代临时变量)

       如果程序以一个临时变量保存某一表达式的运算结果。将这个表达式提炼到一个独立函数中,将这个临时变量的所有引用点替换为对新函数的调用。此后,新函数就可被其他函数使用。代码示例如下:

代码片段 A:

double basePrice = _quantity * _itemPrice;
if(basePrice > 1000) {
    return basePrice * 0.95;
} else {
    return basePrice * 0.98;
}

代码片段 B: 

if(basePrice() > 1000) {
    return basePrice * 0.95;
} else {
    return basePrice * 0.98;
}

double basePrice() {
    return _quantity * _itemPrice;
}

五 Introduce Explaining Variable (引入解释性变量)

       比如你有一个复杂的表达式,可以将该复杂表达式(或其中一部分)的结果放进一个临时变量,将以此变量名称来解释表达式用途。代码示例如下:

代码片段A

if((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1)) && wasInitialized() && resize > 0) {
    //do something
}

代码片段B

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
}

六 Split Temporary Variable (分解临时变量)

       如果某一个临时变量被赋值超过一次,它既不是循环变量,也不被用于手机计算结果。针对每次赋值,创造一个独立、对应的临时变量。代码示例如下:

代码片段A:

double temp = 2 * (_height + _width);
System.out.println(temp);
temp = _height * _width;
System.out.println(temp);

代码片段B:

final double perimeter = 2 * (_height + _width);
System.out.println(perimeter);
final double area = _height * _width;
System.out.println(area);

七 Remove Assignments to Parameters (移除对参数的赋值)

       代码对一个参数进行赋值,以一个临时变量取代该参数的位置。代码示例如下:

代码片段A:

int discount (int inputVal, int quantity, int yearToDate) {
    if(inputVal > 50) inputVal -= 2;
}

代码片段 B:

int discount (int inputVal, int quantity, int yearToDate) {
    int result = inputVal;
    if(inputVal > 50) result -= 2;
}

八 Replace Method with Method Object (以函数对象取代函数)

       如果有一个大型函数,其中对局部变量无法提炼函数,将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。然后你可以在同一个对象中将这个大型函数分解为多个小型函数。

九 Substitute Algorithm (替换算法)

       想要把某个算法替换为另一个更清晰的算法,将函数本体替换为另一个算法。

猜你喜欢

转载自blog.csdn.net/jack1liu/article/details/106962541
03.