首页 > 代码库 > 重新组织函数----Extra Method(提炼函数)

重新组织函数----Extra Method(提炼函数)

你有一段代码可以被组织在一起并独立出来

讲这段代码放在一个独立函数中,并让函数名称解释该函数的用途

范例:无局部变量

void printOwing(double amount){

printBanner();

//printDetail

System.out.println("name:"+_name);

System.out.println("amount:"+amount);

}

重构后代码:

void printOwint(double amount){

printBanner();

printDetail(amount);

}

void printDetail(double amount){

System.out.println("name:"+_name);

    System.out.println("amount:"+amount);

}


动机

Extra Method(提炼函数)是最常用的重构手法之一。当看见一个过长的函数或者一段需要注释才能让人理解用途的代码,就应该将这段代码放进一个独立的函数中去。

范例:有局部变量

果真这么简单?这个重构手法的困难点在哪里?是的,就在局部变量,包括传进源函数的参数和源函数所声明的零时变量。局部变量的作用域仅限于源函数,所以当我使用Extra Method(提炼函数)时,必须花费额外功夫去处理这些变量。某些时候它们可能妨碍我,使我根本无法进行这项重构。
局部变量最简单的情况是:被提炼代码段只是读取这些变量的值,并不修改它们。这种情况可以简单的将它们当作参数传给目标函数

void printOwing{
Enumeration e=orders.elements();
double outstanding=0.0;
printBanner();

//calculate outstanding
while(e.hasMoreElements){
Order order=(Order)e.nextElement();
outstanding +=each.getAmount();
}
System.out.println("name:"+_name);
System.out.println("amount:"+outstanding);

}


就可以讲打印详细信息提炼为带一个参数的函数:
void printOwing{
Enumeration e=orders.elements();
double outstanding=0.0;
printBanner();

//calculate outstanding
while(e.hasMoreElements){
Order order=(Order)e.nextElement();
outstanding +=each.getAmount();
}
printDetails(outstading);
}

void printDetails(double outstanding){
System.out.println("name:"+_name);
System.out.println("amount:"+outstanding);
}

必要的话可以用这种手法处理多个局部变量


范例:对局部变量再赋值


如果被提炼的代码对局部变量赋值,问题就变得复杂了。这里只讨论临时变量的问题。如果你发现源函数的参数被赋值,应该马上使用Remove Assignments to Parameters(131)。
被赋值的临时变量也分为两种情况。较简单的情况是:这个变量只在被提炼的代码段中使用。果真如此,你可以将这个临时变量的声明移动到被提炼的代码段中,然后一起提炼出去。另一种情况是:被提炼代码段之外的代码也使用了这个变量。这又分为两种情况:如果这个变量在被提炼代码段之后再未被使用,你只需要在目标函数中修改它就可以了;如果被提炼代码段之后的代码还使用了这个变量,你就需要让目标函数返回该变量改变后的值。下列代码可以说明这几种不同的情况。

void printOwing(){
Enumeration e=_orders.elements();
double outstanding=0.0;
printBanner();
//calculate outstanding
while(e.hasMoreElements){
Order order=(Order)e.nextElement();
outstanding+=order.getAmount();
}
printDetails(outstanding);

}

现在把“计算”代码提炼出来:
void printOwing(){
printBanner();
double outstanding=getOutstanding();
printDetails(outstanding);

}

double getOutstanding(){
Enumeration e=_orders.elements();
double outstanding=0.0;
while(e.hasMoreElements){
Order order=(Order)e.nextElement();
outstanding+=order.getAmount();
}
return outstading;
}





重新组织函数----Extra Method(提炼函数)