重構之提煉程式碼

liuzongan1985發表於2007-09-26

前幾天北京圖書大廈買了兩本書<<重構,改善既有程式碼的設計>>與<<agile with="" web="" development="" rails=""></agile>><agile with="" web="" development="" rails=""></agile>

特意把書的程式碼一個字一個字粘出來,望能幫助我們這些開發人員對"重構"理解提供一些幫助,

當你有一段程式碼可以被組織在一起獨立出來

將這段程式碼放進一個獨立函式中,並讓函式名稱解釋該函式的用途

函式的命名是非常重要的,以前我做開發的時候,從來我就不考慮這麼多,只要這個函式能跑起來就行,我也不去管那麼多,現在看了"重構",感覺它有另外一種思想,望大家好好學習!!

java 程式碼
  1. void  printOwing(double amonut){   
  2. printBanner();   
  3. //print details
  4. System.out.println("name:"+_name);
  5. System.out.println(""amount:"+amount);
  6.   
  7. }  

 

重構後的程式碼:

java 程式碼
  1. void printOwing(double amonut){   
  2.      printBanner();
  3.      printDetails(amount
  4. }  
  5. void printDetails(double amount){
         System.out.println("name:"+_name);
  6.      System.out.println("amount:"+amount);
  7. }

可以看出現在變成了兩個方法,把一部分語句抽出來做為一個方法!!

Extract Method 是最常見的重構方法之一。看見一個過長的函式或者一段需要註釋才能讓人理解用途的程式碼,就會將這個段程式碼放進一個獨立函式中。

有數個原因造成簡短面有良好的命名的函式。首先,如果每個函式的粒度都江堰市很小(finely grained),那麼函式之間彼此複用的機會就更大了,其次,這會使高層函式程式碼讀起來就像一系列註釋;再者,如果函式都是細粒度,那麼函式的覆寫(override)也會更容易些.

作法:

  • 創造一個新函式,根據這個函式的意圖來給它命名
  • 仔細檢查提煉出的程式碼,看看其中是否引用了(作用域限於源函式)的變數(包括區域性變數和源函式引數)
  • 檢查是否有(僅僅用於被提煉程式碼)的臨時變數,如果有,在目標函式中將它們宣告為臨時變數
  • 檢查被提煉碼,看看是否有任何區域性變數的值被它改變,如果一個臨時變數值被修改了,看看是否可以將被提煉碼處理為一個查詢(Query),並將結果值給相關變數,
  • 將被提煉程式碼中需要讀取的區域性變數,當作函式傳給目標函式

範例1):無區域性變數(No  Local Variables)

java 程式碼
  1. void printOwing()
  2. {     
  3.      Enumeration e =_orders.elements();
  4.      double outstanding=0.0;   
  5.  
  6.      //calculate outstanding 
  7.      System.out.println("*******************************"); 
  8.      System.out.println("********* Customer Owes********"); 
  9.      System.out.pritnln("*******************************");
  10.      
  11.      //calculate outstanding
  12.      while(e.hasMoreElements()
  13.      {
  14.           Order each=(Order)e.nextElement();
  15.           outstanding +=each.getAmount();
  16.    }
  17.  
  18.      //print details
  19.      System.out.println("name:"+_name);
  20.      System.out.println("amount:"+outstanding);
         
  21. }  

 重構後:

java 程式碼
  1. void printOwing(){   
  2.      Enumeration e=_orders.elements();  
  3.      double outstanding=0.0;
  4.      printBanner();
  5.      //calculate outstanding
  6.      while (e.hasMoreElements())
  7.      {
  8.            Order order=(Order)e.nextElement();
  9.            outstanding +=each.getAmount();
          } 
  10.  
  11.       //print details
  12.       System.out.println("name:"+_name);
  13.       System.out.println("amount:"+outstanding);
     
  14. }
  15.  
  16. void printBanner(){
  17.      //print banner
  18.      System.out.println("*******************************";
  19.      System.out.println("*********** Customer Owes *****");
  20.      System.out.println("*******************************"):
    }

 

範例2):對區域性變數再賦值(Reassigning)

java 程式碼
  1. void printOwing(){   
  2.      printBanner();
  3.      double outstanding=getOutstanding();
  4.      printDetails(outstanding);
  5. }  
  6.  
  7. double getOutstanding()
  8. {
  9.    Enumeration e=_orders.elements();
  10.    while (e.hasMoreElements())
  11.    {
  12.       Order each=(Order)e.nextElement();
  13.       outstanding +=each.getAmount();
  14.     }
  15.    return outstanding;
    }

Enumeration 變數 e 只有被提煉碼中用到,所以可以將它整個搬到新函式中,double 變數oustanding 在被提煉碼內外都被用到,所以我必須讓提煉的新函式返回它。

java 程式碼
  1. double getOutstanding()
  2. {   
  3.     Enumeration e=_orders.elements();
  4.     double result=0.0;
  5.     while(e.hasMoreElements())
  6.     {
  7.         Order each=(Order)e.nextElement();
  8.         result +=each.getAmount();
  9.      }
  10.     return result;
    }
  11.   

最後提煉成:

java 程式碼
  1. void print()   
  2. {   
  3.      printBanner();
  4.      double outstanding=getOutstanding();
  5.      printDetails(outstanding);
  6. }  
簡單吧,呵呵

相關文章