文章目录
  1. 1. Extract Method(提炼函数)
    1. 1.1. Before Refactoring
    2. 1.2. After Refactoring
  2. 2. Inline Method(内联函数)
    1. 2.1. Before Refactoring
    2. 2.2. After Refactoring
  3. 3. Inline Temp(内联临时变量)
    1. 3.1. Before Refactoring
    2. 3.2. After Refactoring
  4. 4. Replace Temp with Query(以查询取代临时变量)
    1. 4.1. Before Refactoring
    2. 4.2. After Refactoring
  5. 5. Introduce Explaining Variable(引入解释性变量)
    1. 5.1. Before Refactoring
    2. 5.2. After Refactoring
  6. 6. Split Temporary Variable(分解临时变量)
    1. 6.1. Before Refactoring
    2. 6.2. After Refactoring
  7. 7. Remove Assignments to Parameters(移除对参数的赋值)
    1. 7.1. Before Refactoring
    2. 7.2. After Refactoring
  8. 8. Replace Method with Method Object(以函数对象取代函数)
    1. 8.1. Before Refactoring
    2. 8.2. After Refactoring
  9. 9. Substitute Algorithm(替换算法)
    1. 9.1. Before Refactoring
    2. 9.2. After Refactoring

经历了前面多个概括性的章节阅读之后,终于到了具体的重构实例了,下面我们就慢慢学习,第一个具体重构章节就是Composing Methods(重新组织函数).

Extract Method(提炼函数)

有一段代码可以被组织在一起并独立出来,就将这段代码放进一个独立函数中,并让函数名称解释该函数的用途。

Before Refactoring

void printOwing(double amount) {
    pringtBanner();

    //print details
    System.out.println("name:" + _name);
    System.out.println("amount:" + _amount);
}

After Refactoring

void printOwing(double amount) {
    pringtBanner();
    printDetails(amount);
}

void printDetails(double amount) {
    System.out.println("name:" + _name);
    System.out.println("amount:" + _amount);
}

Inline Method(内联函数)

一个函数的本体与名称同样清楚易懂,在函数调用点插入函数本体,然后移除函数。

Before Refactoring

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

boolean moreThanFiveLateDeliveries() {
    return _numberOfLateDeliveries > 5;
}

After Refactoring

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

Inline Temp(内联临时变量)

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

Before Refactoring

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

After Refactoring

return (anOrder.basePrice() > 1000)

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

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

Before Refactoring

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

After Refactoring

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

double basePrice() {
    return _quantity * _itemPrice;
}

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

有一个复制表达式,可将该复制表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。

Before Refactoring

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

After Refactoring

final boolean isMacOs = platform.toUpperCase().indexof("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexif("IE") > -1;
final boolean wasResized = resize > 0;

if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
    //do something
}

Split Temporary Variable(分解临时变量)

程序中某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立,对应的临时变量。

Before Refactoring

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

After Refactoring

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

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

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

Before Refactoring

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

After Refactoring

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

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

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

Before Refactoring

class Order {
    double price() {
        double primaryBasePrice;
        double secondaryBasePrice;
        double tertiaryBasePrice;
        // long computation;
    }
}

After Refactoring

Substitute Algorithm(替换算法)

将函数本体替换为另一个更加清晰的算法。

Before Refactoring

String foundPerson(String[] people) {
    for (int i=0; i < people.length; i++) {
        if (people[i].equals("Don")) {
            return "Don";
        }
        if (people[i].equals("John")) {
            return "John";
        }
        if (people[i].equals("Kent")) {
            return "Kent";
        }
    }
    return "";
}

After Refactoring

String foundPerson(String[] people) {
    List candidates = Arrays.asList(new String[]{"Don", "John", "Kent"});
    for (int i=0; i < people.length; i++) {
        if (candidates.contains(people[i])) {        
            return people[i];
        }
    }
    return "";
}
文章目录
  1. 1. Extract Method(提炼函数)
    1. 1.1. Before Refactoring
    2. 1.2. After Refactoring
  2. 2. Inline Method(内联函数)
    1. 2.1. Before Refactoring
    2. 2.2. After Refactoring
  3. 3. Inline Temp(内联临时变量)
    1. 3.1. Before Refactoring
    2. 3.2. After Refactoring
  4. 4. Replace Temp with Query(以查询取代临时变量)
    1. 4.1. Before Refactoring
    2. 4.2. After Refactoring
  5. 5. Introduce Explaining Variable(引入解释性变量)
    1. 5.1. Before Refactoring
    2. 5.2. After Refactoring
  6. 6. Split Temporary Variable(分解临时变量)
    1. 6.1. Before Refactoring
    2. 6.2. After Refactoring
  7. 7. Remove Assignments to Parameters(移除对参数的赋值)
    1. 7.1. Before Refactoring
    2. 7.2. After Refactoring
  8. 8. Replace Method with Method Object(以函数对象取代函数)
    1. 8.1. Before Refactoring
    2. 8.2. After Refactoring
  9. 9. Substitute Algorithm(替换算法)
    1. 9.1. Before Refactoring
    2. 9.2. After Refactoring