學習重構(5)-簡化條件表達式

1.Decompose Conditional (分解條件表達式)
應用場景:你有一個複雜的條件(if-then-else)語句。從if、then、else三個段落中分別提煉出獨立函數。
示例:
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
  charge = quantity * mWinterRate + mWinterServiceCharge;
} else {
  charge = quantity * mSummerRate;
}
重構爲:
if (notSummer(date)) {
  charge = winterCharge(quantity);
} else {
  charge = summerCharge(quantity);
}
private boolean notSummer(Date date) {
  return date.before(SUMMER_START) || date.after(SUMMER_END);
}
private double winterCharge(int quantity) {
  return quantity * mWinterRate + mWinterServiceCharge;
}
private double summerCharge(int quantity) {
  return quantity * mSummerRate;
}函數

2.Consolidate Conditional Expression (合併條件表達式)
應用場景:你有一系列條件測試,都獲得相同結果。將這些測試合併爲一個條件表達式,並將這個條件表達式提煉成一個獨立函數。
示例:
double disabilityAmount() {
if(mSeniority < 2) {
return 0;
}
if(mMonthsDisabled > 12) {
return 0;
}
if(mIsPartTime) {
return 0;
}
// compute the disability amount ...
}
重構爲:
double disabilityAmount() {
  if(isNotEligibleForDisability()) {
    return 0;
  }
  // compute the disability amount ...
}
private boolean isNotEligibleForDisability() {
  return (mSeniority < 2) || (mMonthsDisabled > 12) || mIsPartTime;
}測試

3.Consolodate Duplicate Conditional Fragments (合併重複的條件片斷)
應用場景:在條件表達式的每一個分支上有着相同的一段代碼。將這段重複代碼搬移到條件表達式以外。
示例:
if(isSpecialDeal()) {
  total = price * 0.95; send();
} else {
  total = price * 0.98; send();
}
重構爲:
if(isSpecialDeal()) {
  total = price * 0.95;
} else {
  total = price * 0.98;
}
send();orm

4.Remove Control Flag (移除控制標記)
應用場景:在一系列布爾表達式中,某個變量帶有「控制標記」的做用。以break語句或return語句取代控制標記。
示例:void checkSecurity(String[] people) {
  boolean found = false;
  for(int i = 0; i < people.length; i++) {
    if(!found) {
      if(people[i].equals("Don")) {
      sendAlert();
      found = true;
    }
    if(people[i].equals("John")) {
      sendAlert();
      found = true;
} } } }
重構爲:void checkSecurity(String[] people) {
  for(int i = 0; i < people.length; i++) {
    if(people[i].equals("Don")) {
    sendAlert();
    break;
  }
  if(people[i].equals("John")) {
    sendAlert();
    break;
} } }對象

5.Replace Nested Conditional with Guard Clauses (以衛語句取代嵌套條件表達式)
應用場景:函數中的條件邏輯令人難以看清正常的執行路徑。使用衛語句表現全部特殊狀況。
條件表達式常有兩種表現形式:a)全部分支都屬於正常行爲;b)表達分支中只有一種是正常行爲,其餘都是不常見的狀況。若是兩條分支都是正常行爲,就應該使用形如if...else...的條件表達式;若是某個條件極其罕見,就應該單獨檢查該條件,並在該條件爲真時馬上從函數中返回。這樣的單獨檢查常被稱爲「衛語句」。
示例:
double getPayAmount() {
  double result; if(mIsDead) {
    result = deadAmount();
  } else {
    if(mIsSeparated) {
      result = separatedAmount();
    } else {
      if(mIsRetired) {
        result = retiredAmount();
      } else {
        result = normalPayAmount();
} } }
return result;
}ci

重構爲:
double getPayAmount() {
  if(mIsDead) {
    return deadAmount();
  }
  if(mIsSeparated) {
    return separatedAmount();
  }
  if(mIsRetired) {
    return retiredAmount();
  }
  return normalPayAmount();
}get

6.Replace Conditional with Polymorphism (以多態取代條件表達式)
應用場景:你手上有個條件表達式,它根據對象類型的不一樣而選擇不一樣的行爲。將這個條件表達式的每一個分支放進一個子類內的覆寫函數中,而後將原始函數聲明爲抽象函數。
示例:
double getSpeed() {
  switch(mType) {
    case EUROPEAN: return getBaseSpeed();
    case AFRICAN: return getBaseSpeed() - getLoadFactor() * mNumberOfCoconuts;
    case NORWEGIAN_BLUE: return mIsNailed ? 0 : getBaseSpeed(mVoltage);
  }
  throw new RuntimeException("Should be unreachable.");
}it

重構爲:
abstract class Bird {
  abstract double getSpeed();
}io

class European extends Bird {
  double getSpeed() {
  return getBaseSpeed();
} }class

class African extends Bird() {
  double getSpeed() {
  return getBaseSpeed() - getLoadFactor() * mNumberOfCoconuts;
} }變量

class NorwegianBlue extends Bird {
  double getSpeed() {
  return mIsNailed ? 0 : getBaseSpeed(mVoltage);
} }

7. Introduce Null Object (引入Null對象)
應用場景:你須要再三檢查某對象是否爲null,將null值替換爲null對象。
示例:
if (custom == null) {
plan = BillingPlan.basic();
} else {
plan = custom.getPlan();
}
重構爲:
class Custom {
public Plan getPlan() {
return normalPlan;
}

public boolean isNull() {
return false;
}
}

class NullCustom extends Custom {
public Plan getPlan() {
return BillingPlan.basic();
}

public boolean isNull() {
return true;
}
}

8. Introduce Assertion (引入斷言)應用場景:某一段代碼須要對程序狀態作出某種假設。以斷言明確表現這種假設。

相關文章
相關標籤/搜索