文章目录
  1. 1. Rename Method(函数改名)
  2. 2. Add Parameter(添加参数)
  3. 3. Remove Parameter(移除参数)
  4. 4. Separate Query from Modifier(将查询函数和修改函数分离)
    1. 4.1. Before Refactoring
    2. 4.2. After Refactoring
  5. 5. Parameterize Method(令函数携带参数)
  6. 6. Replace Parameter with Explicit Methods(以明确参数取代参数)
    1. 6.1. Before Refactoring
    2. 6.2. After Refactoring
  7. 7. Preserve Whole Object(保持对象完整)
    1. 7.1. Before Refactoring
    2. 7.2. After Refactoring
  8. 8. Replace Parameter with Methods(以函数取代参数)
    1. 8.1. Before Refactoring
    2. 8.2. After Refactoring
  9. 9. Introduce Parameter Object(引入参数对象)
  10. 10. Remove Setting Method(移除设值函数)
  11. 11. Hide Method(隐藏函数)
  12. 12. Replace Constructor with Factory Method(以工厂函数取代构造函数)
    1. 12.1. Before Refactoring
    2. 12.2. After Refactoring
  13. 13. Encapsulate Downcast(封装向下转型)
    1. 13.1. Before Refactoring
    2. 13.2. After Refactoring
  14. 14. Replace Error Code with Exception(以异常取代错误码)
    1. 14.1. Before Refactoring
    2. 14.2. After Refactoring
  15. 15. Replace Exception with Test(以测试取代异常)
    1. 15.1. Before Refactoring
    2. 15.2. After Refactoring

在面向对象技术中,最重要的概念莫过于“接口”。容易被理解和被使用的接口,是开发良好面向对象软件的关键。本章将介绍几个使接口变得更简洁易用的重构方法。

Rename Method(函数改名)

函数的名称未能揭示函数的用途。应该修改函数名称。

Add Parameter(添加参数)

某个函数需要从调用端得到更多信息。

应该为这个函数添加一个对象参数,让该对象带进函数所需信息。

Remove Parameter(移除参数)

函数本体不再需要某个参数,应该将该参数去除。

Separate Query from Modifier(将查询函数和修改函数分离)

某个函数既返回对象状态值,又修改状态。

应该建立两个不同的函数,其中一个复杂查询,另一个复杂修改。

Before Refactoring

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

After Refactoring

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

void sendAlert(String[] people) {
    if (! foundPerson(people).equals("") {
        sendAlert();
    }
}

Parameterize Method(令函数携带参数)

若干函数做了类似的工作,但在函数体中却包含了不同的值。

应该建立单一函数,以参数表达那些不同的值。

Replace Parameter with Explicit Methods(以明确参数取代参数)

有一个函数,其中完全取决于参数值而采取不同行为。

应该针对该参数的每一个可能值,建立一个独立函数。

Before Refactoring

void setValue(String name, int value) {
    if (name.equals("height")) {
        _height = value;
        return;
    }
    if (name.equals("width")) {
        _width = value;
        return;
    }
}

After Refactoring

void setHeight(int arg) {
    _height = arg;
}
void setWidth(int arg) {
    _width = arg;
}

Preserve Whole Object(保持对象完整)

从某个对象中取出若干值,将它们作为某一次函数调用时的参数。

应该改为传递整个对象。

Before Refactoring

int low = daysTempRange().getLow();
int high = daysTempRange().getHigh();
withinPlan = plan.withinRange(low, high);

After Refactoring

withinPlan = plan.withinRange(daysTempRange());

Replace Parameter with Methods(以函数取代参数)

对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能够调用前一个函数。

应该让参数接受者去除该项参数,并直接调用前一个函数。

Before Refactoring

int basePrice = _quantity * _itemPrice;
discountLevel = getDiscountLevel();
double finalPrice = discountPrice(basePrice, discountLevel);

After Refactoring

int basePrice = _quantity * _itemPrice;
double finalPrice = discountPrice(basePrice);

Introduce Parameter Object(引入参数对象)

某些参数总是很自然地同时出现。

应该以一个对象取代这些参数。

Remove Setting Method(移除设值函数)

类中的某个字段应该在对象创建时被设置,然后就不再改变。

应该去掉字段的所有设值函数。

Hide Method(隐藏函数)

有一个函数,从来没有被其他任何类用到。
应该将这个修改为private

Replace Constructor with Factory Method(以工厂函数取代构造函数)

希望在创建对象时不仅仅是做简单的建构工作。

应该将构造函数替换为工厂函数。

Before Refactoring

Employee(int type) {
    _type = type;
}

After Refactoring

static Employee create(int type) {
    return new Employee(type)
}

Encapsulate Downcast(封装向下转型)

某个函数返回的对象,需要由函数调用者执行向下转型。

应该将向下转型动作移到函数中。

Before Refactoring

Object lastReading() {
    return readings.lastElement();
}

After Refactoring

Reading lastReading() {
    return (Reading)readings.lastElement();
}

Replace Error Code with Exception(以异常取代错误码)

某个函数返回一个特定的代码,用以表示某种错误情况。

应该改用异常。

Before Refactoring

int withdraw(int amount) {
    if (amount > _balance) {
        return -1;
    } else {
        _balance -= amount;
        return 0;
    }
}

After Refactoring

void withdraw(int amount) throws BalanceException {
    if (amount > _balance) {
        throws new BalanceException();
    }
    _balance -= amount;
}

Replace Exception with Test(以测试取代异常)

面对一个调用者可以预先检查的条件,你抛出了一个异常。

应该改用调用者,使它在调用函数之前先做检查。

Before Refactoring

double getValueForPeriod(int periodNumber) {
    try {
        return _values[periodNumber];
    } catch(ArrayIndexOutOfBoundsException e) {
        return 0;
    }
}

After Refactoring

double getValueForPeriod(int periodNumber) {
    if (periodNumber >= _values.length) {
        return 0;
    }
    return _values[periodNumber];
}

异常应该只用于异常的,罕见但行为,也就是那些产生意料之外的错误的行为,而不是成为条件检查的替代品。

文章目录
  1. 1. Rename Method(函数改名)
  2. 2. Add Parameter(添加参数)
  3. 3. Remove Parameter(移除参数)
  4. 4. Separate Query from Modifier(将查询函数和修改函数分离)
    1. 4.1. Before Refactoring
    2. 4.2. After Refactoring
  5. 5. Parameterize Method(令函数携带参数)
  6. 6. Replace Parameter with Explicit Methods(以明确参数取代参数)
    1. 6.1. Before Refactoring
    2. 6.2. After Refactoring
  7. 7. Preserve Whole Object(保持对象完整)
    1. 7.1. Before Refactoring
    2. 7.2. After Refactoring
  8. 8. Replace Parameter with Methods(以函数取代参数)
    1. 8.1. Before Refactoring
    2. 8.2. After Refactoring
  9. 9. Introduce Parameter Object(引入参数对象)
  10. 10. Remove Setting Method(移除设值函数)
  11. 11. Hide Method(隐藏函数)
  12. 12. Replace Constructor with Factory Method(以工厂函数取代构造函数)
    1. 12.1. Before Refactoring
    2. 12.2. After Refactoring
  13. 13. Encapsulate Downcast(封装向下转型)
    1. 13.1. Before Refactoring
    2. 13.2. After Refactoring
  14. 14. Replace Error Code with Exception(以异常取代错误码)
    1. 14.1. Before Refactoring
    2. 14.2. After Refactoring
  15. 15. Replace Exception with Test(以测试取代异常)
    1. 15.1. Before Refactoring
    2. 15.2. After Refactoring