重構之簡化條件運算式

來源:互聯網
上載者:User

      條件邏輯有可能十分複雜,因此本章提供一些重構手法,專門用來簡化它們。其中一項核心重構就是Decompose Conditional,可將一個複雜的條件邏輯分成若干小塊。這項重構很重要,因為它使邏輯和操作細節的分離。

     本章的其餘重構手法可用以處理另一些重要問題,如果你發現代碼中的多處測試有相同的結構,應該實施Consolidate Conditional Expression,如果條件代碼中有任何重複,可以運用Consolidate Duplicate Conditional Fragment 將重複成分去掉。

      較之於過程化程式而言,物件導向因為多態的機制可以簡化條件行為的細節

1. Replace Nested Condition with Guard Clauses(以衛語句

取代嵌套條件運算式) 

        Clauses[klɔ:zis] :字句      Guard[ga:d]: 守衛、看守    Nesting: 嵌套

        範例:

               想象一個薪酬系統,其中以特區規則處理死亡、駐外、退休員工的薪資,這些情況不常有,但偶然會出現

         常規編碼:

   1:      private double getPlayAmount(){
   2:          double result;
   3:          if(_isDead){
   4:              result = deadAmount();
   5:          }else{
   6:              if(_isSeparated){
   7:                  result = separatedAmount();
   8:              }else {
   9:                  if(_isRetired){
  10:                      result = retiredAmount();
  11:                  }else {
  12:                      result = normalAmount();
  13:                  }
  14:              }
  15:          }
  16:          return result;
  17:      }
 
   分析: 條件運算式通常有兩種表現形式。第一種:所有的分支都屬於正常行為,應該用
             if..else表達出來。第二種:條件運算式提供的答案中只有一種是正常行為,其
             他都是不常見的行為。此時就要單獨檢查該條件,並在該條件為真時立刻從函數
             中返回,這種單獨檢測常常為稱為“衛語句”通過分析題意,我們知道該函數主
             體是付普通情況的工資,而死亡、駐外、退休屬於特區情況,因此我們把他們做
             為衛語句處理,修改後為:
      
   1:      private double getPlayAmount(){
   2:          
   3:          if(_isDead){
   4:              return deadAmount();
   5:          }
   6:          
   7:          if(_isSeparated){
   8:              return separatedAmount();
   9:          }
  10:          
  11:          if(_isRetired){
  12:              return retiredAmount();
  13:          }
  14:   
  15:          return normalAmount();
  16:      }
 

     2. Decompose Conditional (分解條件運算式) 

        decompose [ˌdi:kəmˈpəuz] :分解、腐爛

         -----你有一個複雜的條件陳述式(if、then、else),從if ,then,else三個段落中分別提煉出獨立函數

         假設我要計算購買某樣商品的總價(總價=數量 * 單價),而這個商品在冬季和夏季的單價是不同的。

    if(data.before(SUMMER_START) || data.after(SUMMER_END)){        charge = quantity * _winterRate ;    }else{        charge = quantity * _summerRate    }

        分析:複雜的條件邏輯是最常導致複雜度上升的原因之一,常見的做法是1) 將if段提煉出來,構成一個獨立的函數  2)將then和else段提煉出來構成一個獨立的函數

        修改後的代碼為:

    if(notSummer(data)){        charge = winterCharge(quantity);    }else{        charge = summerCharge(quantity);    }        private boolean notSummer(Data data){        return data.before(SUMMER_START) || data.after(SUMMER_END);    }        private double summerCharge(int quantity){        return quantity * _summerRate;    }        private double winterCharge(int quantity){        return quantity * _winterRate;    }

     通過以上的簡化,條件運算式邏輯塊就像代碼注釋一樣清晰、明了

3. Consolidate Conditional Expression (合并條件運算式)       

       ----你有一系列的條件測試,都得到相同的結果,將這些測試合并為一個條件運算式,並將這個條件運算式提煉為一個獨立的函數

       樣本:

    double disabilityAmount(){        if(_seniority < 2){            return 0;        }        if(_months > 12){            return 0;        }        if(_isPartTime){            return 0;        }    }

      分析:有時候你會發現一連串的檢查條件,雖然條件各不相同,但是最終行為卻一致,這種情況一般是用“邏輯與”或者“邏輯或”把他們合并為一個條件運算式,使代碼更清楚。 合并後

    double disabilityAmount(){        if(isNotAbility()){            return 0        }    }        boolean isNotAbility(){        return ((_seniority < 2) || (_months > 12) || _isPartTime)    }
4. Consolidate Duplicate Conditional Fragements(合并重複的
    條件片段)
       ---在條件運算式的每個分支上有著相同的一段代碼
    if(isBook){        total = price * 0.95;        send();    }else{        total = price * 0.5;        send();    }
    分析: 針對這種情況,應該將重複的代碼搬移到條件運算式的外面,這樣代碼才能夠更加清
          楚的表明那些東西隨條件的變化而變化,那些東西保持不變
    if(isBook){        total = price * 0.95;    }else{        total = price * 0.5;    }    send();

5. Replace Conditional with Polymorphism(以多態取代條件

運算式)

    如果需要根據對象的不同類型而採取不同的行為,多態使你不需要編寫明顯的條件運算式。比如重構第一章我們提到的電影分兒童、新片、普通片。這三種片都是電影的不同類型,我們可以定義一個電影的抽象類別,然後利用多態的性質,讓不同的類型的電影去繼承,這樣我們就可以去掉多餘的條件判斷

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.