提出问题

项目开发中如何简化函数调用???

解决问题

以下来自《重构》的简单总结:

Rename Method(函数改名)

函数的名称皆是函数的用途。一个好的函数名称可以体现一个程序员的水平和素养。

Add Parameter(添加参数)

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

请记住,在之前的文章中有提到,如果一个函数的参数超过3个,那么这个函数就需要重构

Remove Parameter(移除参数)

函数本体不再需要这个参数,将该参数去除。(将多余参数删除,不要留下坏味道)

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

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

Parameterize Method(令函数携带参数)

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

重构前:

  1. class Employee{
  2. void tenPercentRaise(){
  3. salary *= 1.1;
  4. }
  5. void fivePercentRaise(){
  6. salary *= 1.05;
  7. }
  8. }

重构后:

void raise(double factor){
   salary *= (1 + factor)
}

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

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

Preserve Whole Object(保存对象完整)

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

重构前:

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

重构后:

withinPlan = plan.withinRange(daysTempRange())

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

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

重构前

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

重构后:

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

Introduce Parameter Object(引入参数对象)

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

代码用一对值来表示一个范围。例如表示日期范围的开始和结束,表示数值范围的upper和lower等等。

Remove Setting Method(移除设置函数)

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

Hide Method(隐藏函数)

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

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

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

Encapsulate Downcast(封装向下转型)

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

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

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

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

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

重构前:

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

重构后:

double getValueForPeriod(int periodNumber){
//在这里提前检查条件,而不是滥用异常
if(periodNumber >= _values.length) return 0
return _values(periodNumber);
}

不是一种意料外的事件,并不应该抛异常