《重构 改善既有代码的设计》 第十章 --简化函数调用
本章将介绍几个使接口变得更简洁易用的重构手法。
函数改名(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];
}
















