《重構——改善既有代碼》
Motivation
出現依戀情節或者職責不清,應將行為移動到正確的類中。
 
Mechanics
 
1  檢查源函數中所使用一切特性(包括field和函數)
2  檢查子類和父類是否也定義了該函數
3  先委託,然後根據實際情況,決定是否將對源函數的調用替換為對目標函數的調用。 
 Eclipse refactor菜單下直接有Move 選項,可以直接使用該選項完成Move Method重構。但實際應用中,還是有一些細緻的不同,下面詳細說明:
預設情形:[Move] method,  必須要求源類中必須以目標類對象為成員變數,否則找不到目標對象。另外,移動後,預設總是以源類對象作為函數參數。
特殊情形1:目標類是源類的內部類,實際使用copy代碼的方法。
特殊情形2:目標類中成員中已經有源類的對象,實際使用[Move] + [Rename] + [Change Method Signature]的方法
特殊情形3:有時候,只需要將源類的一個成員變數作為函數參數傳入,而沒有必要傳入整個源類對象。實際使用[ExtractLocal Variable] + [Introduce Parameter] / [Extract Method]   + [Move],
也可以使用[ExtractLocal Variable] + [Extract Method]  + [Inline] + [Move]
 
double bankCharge(Account account) {double result = 4.5;if (account._daysOverdrawn > 0)result += account.overdraftCharge();return result;}
 
 
// 1.  對需要move的函數中的成員變數,應用[Extract Local Variable]替換為局部變數,同時必然會增加“localVariable = _field”這樣一句指派陳述式。
publicclass Account {
    double overdraftCharge() {
        finalintdaysOverdrawn =_daysOverdrawn;
        if (_type.isPremium()) {
            double result = 10;
            if (daysOverdrawn> 7)
                result += (daysOverdrawn - 7) * 0.85;
            return result;
        } else
            returndaysOverdrawn* 1.75;
}
 // 2. 對上面新增的指派陳述式"final int daysOverdrawn = _daysOverdrawn;",選中field " _daysOverdrawn",應用Introduce Parmeter,將該field作為函數參數傳入。
 
public class Account {
    double overdraftCharge(int dayOverdrawn) {
       
 
 final
 
 
 
 int
 
 
 daysOverdrawn =
 _daysOverdrawn;
 
        final int daysOverdrawn = dayOverdrawn;
        
 if (
 _type.isPremium()){ 
// 3.   刪除該指派陳述式”localVariable = _field”。
public class Account {
    double overdraftCharge(int dayOverdrawn) {
       
 
 final
 
 
 
 int
 
 
 daysOverdrawn =
 dayOverdrawn;
 
        
 if (
 _type.isPremium()){
=========================================================================================
還有一種更通用的調整方法,其核心思想是將舊方法介面委託給新方法,然後應用內聯將所有舊方法替換為新方法,最後move。
第一步同上,第二步改為使用[Extract Method],將 指派陳述式"final int daysOverdrawn = _daysOverdrawn;"以下的部分抽取為新的函數,函數名與目標函數相同,都是overdraftCharge.
 
public classAccount {
    double overdraftCharge() {
        final int daysOverdrawn = _daysOverdrawn;
        return overdraftCharge(daysOverdrawn);
    }
    private double overdraftCharge(final int daysOverdrawn) {
        if (_type.isPremium()){
            double result = 10;
            if (daysOverdrawn > 7)
                result +=(daysOverdrawn - 7) * 0.85;
            return result;
        } else
            return daysOverdrawn * 1.75;
     } 
//3. 使用[Inline]替換掉目標函數
先對daysOverdrawn應用[Inline]
 
double overdraftCharge() {
        
 
 final
 
 
 
 int
 
 
 daysOverdrawn =
 _daysOverdrawn;
 
        return overdraftCharge(_daysOverdrawn);
    }
 再對overdraftCharge() 應用[Inline]
 
 
 double
 
 
 overdraftCharge() {
 
 
        
 
 
 return
 
 
 overdraftCharge(
 
 
 _daysOverdrawn
 
 
 );
 
 
     }
 
原來調用overdraftCharge()的地方自動調整為 overdraftCharge(_daysOverdrawn)
result += overdraftCharge();  -->  result += overdraftCharge(_daysOverdrawn);
 
over
以上完整源碼可以在here下載