提取方法(Extract Method)是最常用的重构手法之一。当看到一个方法过长或者方法很难让人理解其意图的时候,这时候就可以用提取方法这种重构手法。

 

下面是我学习这个重构手法的笔记:

 

提取方法看起来好像仅仅是将被提取方法中的一段代码,放到目标方法中。其实,当方法足够复杂的时候,提取方法也会变得复杂。当然,如果提取方法这种重构手法无法进行时,就可能需要选择其他重构手法来进行了。

 

为了更方便的看出重构的效果,重构前的代码为:

Java代码  收藏代码
  1. public void printOwing() {  
  2.     double outstanding = 0.0;  
  3.     Enumeration e = _orders.elements();  
  4.           
  5.     System.out.println("****************************");  
  6.     System.out.println("******* Customer Owes ******");  
  7.     System.out.println("****************************");  
  8.           
  9.     while (e.hasMoreElements()) {  
  10.         Order v = (Order) e.nextElement();  
  11.         outstanding += v.getAmount();  
  12.     }  
  13.           
  14.     // print result  
  15.     System.out.println("name: " + _name);  
  16.     System.out.println("amount: " + outstanding);  
  17. }  

 

 

提取方法分为三种常见的情况,这三种情况分三个步骤进行:

第1步  无局部变量

代码代码  收藏代码
  1. public void printOwing() {  
  2.     double outstanding = 0.0;  
  3.     Enumeration e = _orders.elements();  
  4.           
  5.     printBanner();  
  6.           
  7.     while (e.hasMoreElements()) {  
  8.         Order v = (Order) e.nextElement();  
  9.         outstanding += v.getAmount();  
  10.     }  
  11.           
  12.     System.out.println("name: " + _name);  
  13.     System.out.println("amount: " + outstanding);  
  14. }  
  15.       
  16. public void printBanner() {  
  17.     System.out.println("****************************");  
  18.     System.out.println("******* Customer Owes ******");  
  19.     System.out.println("****************************");  
  20. }  

 

第2步  有局部变量,但目标方法仅读取它

代码代码  收藏代码
  1. public void printOwing() {  
  2.     double outstanding = 0.0;  
  3.     Enumeration e = _orders.elements();  
  4.           
  5.     printBanner();  
  6.           
  7.     // calculate outstanding  
  8.     while (e.hasMoreElements()) {  
  9.         Order v = (Order) e.nextElement();  
  10.         outstanding += v.getAmount();  
  11.     }  
  12.           
  13.     printDetails(outstanding);  
  14. }  
  15.       
  16. public void printBanner() {  
  17.     System.out.println("****************************");  
  18.     System.out.println("******* Customer Owes ******");  
  19.     System.out.println("****************************");  
  20. }  
  21.   
  22. public void printDetails(double outstanding) {  
  23.     System.out.println("name: " + _name);  
  24.     System.out.println("amount: " + outstanding);  
  25. }  

 

第3步  有局部变量,并且目标方法有对其进行赋值

代码代码  收藏代码
  1. public void printOwing() {  
  2.     printBanner();  
  3.     double outstanding = getOutstanding();  
  4.     printDetails(outstanding);  
  5. }  
  6.       
  7. public void printBanner() {  
  8.     System.out.println("****************************");  
  9.     System.out.println("******* Customer Owes ******");  
  10.     System.out.println("****************************");  
  11. }  
  12.   
  13. public void printDetails(double outstanding) {  
  14.     System.out.println("name: " + _name);  
  15.     System.out.println("amount: " + outstanding);  
  16. }  
  17.       
  18. public double getOutstanding() {  
  19.     double outstanding = 0.0;  
  20.     Enumeration e = _orders.elements();  
  21.       
  22.     while (e.hasMoreElements()) {  
  23.         Order v = (Order) e.nextElement();  
  24.         outstanding += v.getAmount();  
  25.     }  
  26.         return outstanding;  
  27. }  

 

总结一下,选择提炼方法这种重构手法有三种好处:

1.每个方法足够细粒度,那么就很方便进行代码复用

2.高层次的方法阅读的时候就像注释一样清晰明了

3.如果方法都是细粒度,方法的复写也会变得更容易一些

posted on 2018-02-06 15:08  Sharpest  阅读(248)  评论(0)    收藏  举报