本章将介绍几个使接口变得更简洁易用的重构手法。
函数改名(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]; }