第10章 简化函数调用

本章将介绍几个使接口变得更简洁易用的重构手法。

函数改名(Rename Method)

1.概念:

函数的名称未能揭示函数的用途,则修改函数名称。emmmm...通俗易懂。

添加参数(Add Parameter)

1.概念:

某个函数需要从调用端得到更多的信息,为此函数添加一个对象参数,让该对象带进函数所需信息。

2动机:

你必须修改一个函数,而修改后的函数需要一些过去没有的信息,因此你需要给该函数添加一个参数。

移除参数(Remove Parameter)

1.概念:

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

2.动机:

参数代表函数所需要的信息,函数调用者必须为每一个参数操心该传什么东西进去,于是有了多余的参数,就应该去掉,而不是想着以后可能会用且目前没错就不管了。

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

1.概念;

某个函数既返回对象状态值,又修改对象状态,则建立两个不同的函数,其中一个负责查询,另一个负责修改。

单一 职责原则吧。

令函数携带参数(Parameterize Method)

1.概念:

若干函数做了类似的工作,但在函数本体中却包含了不同的值。则建立单一函数,以参数表达那些不同的值。

2.动机:

你可能发现有着这样两个函数:它们做着类似的工作,但只因少数几个值致使行为略有不同。这时就可以将这两个各自分离的函数统一起来,并通过参数处理。

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

1.概念:

你有一个函数,其中完全取决于参数值而采取不同的行为。则针对该参数的每一个可能值,建立一个独立函数。

原来下面常用的这个是优胜劣汰,自然选择后的结果:

//改变前
void setValue(String name, int value) {
    if (name.equals("height")) {
        height = value;
        return;
    }
    if (name.equals.("width")) {
        width = value;
        return;
    }
}

//改变后
void setHeight(int arg) {
    height = arg;
}
void setWidth(int arg) {
    width = arg;
}

保持对象完整(Preserve Whole Object)

1.概念:

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

即:将传入参数封装成对象传入。

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

1.概念:

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

2.动机:

如果函数可以通过其他途径获得参数值,则它不应该通过参数获得该值。

//修改前
int basePrice = A * B;
discountLevel = getDiscountLevel();
double finalPrice = discountedPrice(basePrice, discountLevel);

//修改后(已经是编程习惯了的,注意不要犯错犯回去就好)
int basePrice = A * B;
double finalPrice = discountedPrice(basePrice);

3.坏味道:

过长参数列会增加程序阅读者的理解难度,因此我们应该尽可能缩短参数列的长度。

引入参数对象(Introduce Parameter Object)

1.概念:

某些参数总是很自然地同时出现,则以一个对象取代这些参数。

2.动机:

当一组参数总是一起被传递。可能有好几个函数都使用这一组参数,这些函数可能属于同一个类,也可能属于不同类,这样一组参数就是所谓的数据泥团。我们可以用对象包装,以对象取代他们。

移除设值函数(Remove Setting Method)

1.概念:

类中的某个字段应该在对象创建时被设值,然后就不再改变,则去掉该字段的所有设值函数。

2.动机:

如果你不希望在对象创建后此字段还有机会被改变,则不要给这个对象提供设值函数(同时将该字段设为final)

隐藏函数(Hide Method)

1.概念:

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

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

1.概念:

你希望在创建对象的时候不仅仅是做简单的建构动作,则将构造函数替换为工厂函数。

略。。

封装向下转型(Encapsulate Downcast)

1.概念:

某个函数返回的对象,需要由函数调用者执行向下转型,则向下转型动作移到函数中。

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

//将向下转型移动到函数中
Reading lastReading() {
    return (Reading) readings.lastElement();
}

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

1.概念:

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

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

//改变后
void withdraw(int amount) throws BalanceException {
    if (amount > balance) throw new BalanceException();
    balance -= amount;
}

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

1.概念:

面对一个调用者可以预先检查的条件,你抛出了一个异常,则修改调用者,使他在调用函数前先做检查。

//直接抛出异常
public double getValueForPeriod(int periodNumber) {
    try {
        return ...
    } catch (ArrayIndexOutOfBoundsException e) {
        return 0;
    }
}

//先检查,再抛出异常
public double getValueForPeriod(int periodNumber) {
    if (periodNumber >= values.length) return 0;
    return values[periodNumber];
}
原文地址:https://www.cnblogs.com/wencheng9012/p/13566450.html