Extract Method(提炼函数)
void printOwing(double amount){
printBanner();
// print details
System.out.println("name:" + _name);
System.out.println("amount" + amount);
}
修改后:
void printOwing(double amount){
printBanner();
printDetails(amount);
}
void printDetails(double amount){
System.out.println("name:" + _name);
System.out.println("amount" + amount);
}
做法
- 创造一个新函数,根据这个函数的意图来对它命名(以它”做什么”来命名,而不是以它”怎么做”命名)
即使你想要提炼的代码非常简单,例如只是一条消息或一个函数调用,只要新函数的名称能够以更好的方式昭示代码意图,你也应该提炼它。但如果你想不出一个更有意义的名称,就别动
将提炼出来的代码从源函数复制新建的目标函数中
仔细检查提炼出的代码,看看其中是否引用了”作用域限于源函数”的变量(包括局部变量和源函数参数)
检查是否有”仅用于被提炼代码段”的临时变量。如果有,在目标函数中将它们声明为临时变量
检查被提炼代码段,看看是否有任何局部变量的值被它改变。如果一个临时变量值被修改了,看看是否可以将被提炼代码段处理为一个查询,并将结果赋值给相关变量。如果很难这样做,或如果被修改的变量不止一个,你就不能仅仅将这段代码原封不动地提炼出来。你可能需要先使用Split Temporary Variable(分解临时变量),然后再尝试提炼。也可以使用Replace Temp with Query(以查询取代临时变量)将临时变量消灭掉
将被提炼代码段中需要读取的局部变量,当作参数传给目标函数
处理完所有局部变量之后,进行编译
在源函数中,将被提炼代码段替换为对目标函数的调用
如果你将任何临时变量移到目标函数中,请检查它们原本的声明式是否在被提炼代码段的外围。如果是,现在你可以删除这些声明式了
- 编译,测试
范例
范例:无局部变量
void printOwing(){
Enumeration e = _order.elements();
double outstanding = 0.0;
// pring banner
System.out.println("*************************");
System.out.println("***** Customer Owes *****");
System.out.println("*************************");
// calculate outstanding
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
// print details
System.out.println("name:"+_name);
System.out.println("amount"+outstanding);
}
修改后:
void printOwing(){
Enumeration e = _order.elements();
double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
// print details
System.out.println("name:"+_name);
System.out.println("amount"+outstanding);
}
void printBanner(){
System.out.println("*************************");
System.out.println("***** Customer Owes *****");
System.out.println("*************************");
}
范例:有局部变量
void pringOwing(){
Enumeration e = _order.elements();
double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
// print details
System.out.println("name:"+_name);
System.out.println("amount"+outstanding);
}
修改后:
void printOwing(){
Enumeration e = _order.elements();
double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
printDetails(outstanding);
}
void printDetails(double outstanding){
System.out.println("name:"+_name);
System.out.println("amount"+outstanding);
}
范例:对局部变量再赋值
void printOwing(){
Enumeration e = _order.elements();
double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
printDetails(outstanding);
}
修改后:
void printOwing(){
printBanner();
double outstanding = getOutstanding();
printDetails(outstanding);
}
double getOutstanding(){
Enumeration e = _order.elements();
double result = 0.0;
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}
void printOwing(double previousAmount){
printBanner();
double outstanding= getOutstanding(previousAmount * 1.2);
printDetails(outstanding);
}
double getOutstanding(double initialValue){
double result = initialValue;
Enumeration e = _order.elements();
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}