你有1段代码可以被组织在1起并独立出来
讲这段代码放在1个独立函数中,并让函数名称解释该函数的用处
范例:无局部变量
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(提炼函数)是最经常使用的重构手法之1。当看见1个太长的函数或1段需要注释才能让人理解用处的代码,就应当将这段代码放进1个独立的函数中去。
范例:有局部变量
果真这么简单?这个重构手法的困难点在哪里?是的,就在局部变量,包括传进源函数的参数和源函数所声明的零时变量。局部变量的作用域仅限于源函数,所以当我使用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);
}
就能够讲打印详细信息提炼为带1个参数的函数:
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)。
被赋值的临时变量也分为两种情况。较简单的情况是:这个变量只在被提炼的代码段中使用。果真如此,你可以将这个临时变量的声明移动到被提炼的代码段中,然后1起提炼出去。另外一种情况是:被提炼代码段以外的代码也使用了这个变量。这又分为两种情况:如果这个变量在被提炼代码段以后再未被使用,你只需要在目标函数中修改它就能够了;如果被提炼代码段以后的代码还使用了这个变量,你就需要让目标函数返回该变量改变后的值。以下代码可以说明这几种不同的情况。
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;
}