1、Extract Method:提炼方法

将有些代码单独提取出来放入到一个独立的函数中,并让函数名称来解释该函数的用途。

 

[java] view plain copy
 
  1. public void printOwing(double amount) {  
  2.     printBanner();  
  3.     System.out.println("name:" + name);  
  4.     System.out.println("amount:" + amount);  
  5. }  

可以写成:

 

 

[java] view plain copy
 
  1. public void printOwing(double amount) {  
  2.     printBanner();  
  3.     printDetails(amount);  
  4. }  
  5.   
  6. /** 
  7.  * 描述:打印详情 
  8.  */  
  9. public void printDetails(double amount) {  
  10.     System.out.println("name:" + name);  
  11.     System.out.println("amount:" + amount);  
  12. }  

当看到一个过长的函数或需要注释才能让人理解的代码,应该考虑将这段代码放到一个单独的独立函数中。

 

做法:

1、创建一个新的函数,根据函数的意图来命名。

2、将提炼出来的代码从源函数(source)中拷贝到目标函数(target)中。

3、仔细检查提炼出来的代码,看其中是否引用了作用域仅限于源函数的变量。

4、检查是否有仅限于被提炼码的临时变量,如果有,在目标函数中将它申明为局部变量。

5、检查提炼码,看是否有任何局部变量的值被改变,如果有一个临时变量的值被改变,看是否能够将提炼码处理为一个查询,并将结果赋值给临时变量。

6、被提炼码中需要读取的局部变量,通过参数传递给目标函数。

7、处理完所有局部变量后编译,在源函数中替换目标函数,测试。

例子:

 

[java] view plain copy
 
  1. private String name;  
  2. private Vector<Order> orders = new Vector<Order>();  
  3.   
  4. public void printOwing() {  
  5.     Enumeration env = orders.elements();  
  6.     double totalAmount = 0.0;  
  7.     System.out.println("****************");  
  8.     System.out.println("***** test *****");  
  9.     System.out.println("****************");  
  10.   
  11.     while (env.hasMoreElements()) {  
  12.         Order order = (Order) env.nextElement();  
  13.         totalAmount += order.getAmout();  
  14.     }  
  15.   
  16.     System.out.println("name:" + name);  
  17.     System.out.println("amount:" + totalAmount);  
  18. }  

提取没有局部变量的函数:

 

 

[java] view plain copy
 
  1. private void printBanner() {  
  2.     System.out.println("****************");  
  3.     System.out.println("***** test *****");  
  4.     System.out.println("****************");  
  5. }  

提取有局部变量的函数:

 

如果被提炼码只是需要读取这些变量的值,并不修改他们,这时候我们只需要将它作为一个参数传递给目标函数即可,例:

 

[java] view plain copy
 
  1. public void printDetails(double amount) {  
  2.     System.out.println("name:" + name);  
  3.     System.out.println("amount:" + amount);  
  4. }  

如果被提炼码对局部变量进行赋值:

 

1、这个变量只是在提炼码区域中使用,那么可以将这个临时变量的申明式移动到提炼码中,然后一起提炼出去。

2、如果被提炼码之外的代码也使用了这个变量,可分为:

     1)、如果这个变量在被提炼码之后未再被使用,只需要在目标函数中修改它的值即可。

     2)、如果在提炼码之后还要使用该变量,这个时候就需要让目标函数返回该变量改变后的值。

1、提取getTotalAmount():

 

[java] view plain copy
 
  1. /** 
  2.  * 描述:获取总账户余额 
  3.  */  
  4. public double getTotalAmount() {  
  5.     double totalAmount = 0.0;  
  6.     Enumeration env = orders.elements();  
  7.     while (env.hasMoreElements()) {  
  8.         Order order = (Order) env.nextElement();  
  9.         totalAmount += order.getAmount();  
  10.     }  
  11.     return totalAmount;  
  12. }  

这个时候的getOwing()可写成:

 

 

[java] view plain copy
 
  1. public void printOwing() {  
  2.     printBanner();  
  3.     double totalAmount = getTotalAmount();  
  4.     printDetails(totalAmount);  
  5. }  

这里如果totalAmount初始值不是0,而有一个初值,这个时候就需要将这个初值传入到目标函数中去。

 

[java] view plain copy
 
  1. public void printOwing(double initAmount) {  
  2.     printBanner();  
  3.     double totalAmount = initAmount * 1.5;  
  4.     totalAmount = getTotalAmount(totalAmount);  
  5.     printDetails(totalAmount);  
  6. }  
  7.   
  8. /** 
  9.  * 描述:获取总账户余额 
  10.  */  
  11. public double getTotalAmount(double initAmount) {  
  12.     double totalAmount = initAmount;  
  13.     Enumeration env = orders.elements();  
  14.     while (env.hasMoreElements()) {  
  15.         Order order = (Order) env.nextElement();  
  16.         totalAmount += order.getAmount();  
  17.     }  
  18.     return totalAmount;  
  19. }  

临时变量往往很多,这个时候可以考虑Replace Temp with Query(以查询方法替代临时变量),如果这样依旧困难,可以考虑Replace method with method object(以函数变量替换函数)。

 

posted on 2018-02-06 09:33  Sharpest  阅读(1678)  评论(0)    收藏  举报