簡化條件表達式

我們在編寫代碼的過程中,有時會因為復雜的業務,導致我們編寫的代碼圈復雜度過大,if...then...else 過多嵌套,寫完的代碼可能是這樣...

from internet

這種代碼給人的第一感覺就是很美膩(對稱美),除此之外,我想不到了...... 但它的壞處就很明顯了。在寫這個代碼的時候也許只有兩個人可以懂(上帝和你自己),寫完之后我想可能就只有一個人懂了(不是你自己。而是上帝)。

當然了這樣的代碼如果沒有 bug 還好,萬一遇到了 bug 而原作者又不在,那么這段神奇的代碼將可能會被另一個(yu)神(mei)奇的作者換成另一段神奇的代碼,并以此 loop 下去......

So...... 如果這是自己寫的代碼,那么趁著還沒人發現,趕緊重構下吧...

1 Decompose Conditional(分解條件表達式)

怎么說

將 `if...then...else` 中的代碼塊抽離出來

為什么

提高代碼可讀性

怎么做

先來看段代碼
eg:假如一家商場對商品進行打折,價格在 100 - 200 之間的打八折,其它的按原價出售((hen)不(bie)合(jiao)適的栗子)。

function calculatePrice(price) {
  let result;

  if (price >= 100 && price < 200) {
    result = price * 0.8;
  } else {
    result = price;
  }

  return result;
}

代碼很簡單,好像沒什么好重構的,但是代碼想要表達的意圖和業務的聯系并不是很大,也就是說我們把前面對業務的介紹去掉,那么代碼就不具備任何可讀性了(代碼不能很好的表達自己的用途),現在我們對代碼進行重構。

function calculatePrice(price) {
  let result;

  if (isDiscount(price)) {
    result = discount(price);
  } else {
    result = price;
  }

  return result;
}

function isDiscount(price) {
  return price >= 100 && price < 200;
}

function discount(price) {
  return price * 0.5;
}

現在我們再來讀這段代碼,會發現可讀性提高了,我們在讀到第一個if時,我們不需要再去思考里這個判斷語句是什么意思,我們可以直接根據方法名 isDiscount() 就可以知道,這是在判斷是否需要打折,需要的話就打折,不需要的話原價返回,這樣我們就可以把注意力放在代碼的整體邏輯上,而不需要在把過多的注意力放在細節方面。

2 Consolidate Conditional Expression(合并條件表達式)

怎么說

把結果相同的條件表達式合并成一個獨立的函數。

為什么

提高代碼可讀性

怎么做

再來個蹩腳的栗子
eg:某商場再次打折商品,價格大于200的商品打五折,前提是要買夠五件該商品。

function calculatePrice(price, num) {
  if (price < 200) return price * num;
  if (num < 5) return price * num;
  return price * num * 0.5;
}

先蹩說話,先進行第一步重構


function calculatePrice(price, num) {
  if (price > 200 || num < 5) return price * num;
  return price * num * 0.5;
}

第二步重構請參考 Decompose Conditional

3 Consolidate Duplicate Conditional Fragments (合并重復的條件片段)

怎么說

將條件表達式內的重復語句塊搬移到條件表達式外

為什么

減少重復代碼

怎么做
比較簡單,就直接上代碼

function calculatePrice(price) {
  let result;

  if (price <  200) {
    result = discount(price);
    result -= 10; //重復代碼
  } else {
    result = price;
    result -= 10;//重復代碼
  }

  return result;
}

重構下


function calculatePrice(price) {
  let result;

  if (price < 200) {
    result = discount(price);
  } else {
    result = price;
  }
  result -= 10;
  
  return result;
}
4 Replace Nested Conditional with Guard Clauses(以衛語句替代嵌套條件表達式)

怎么說

使用衛語句表示所有的特殊情況(一旦找到結果就可以立即返回)

衛語句: 如果某個條件比較特殊,就應該單獨檢查該條件,并當該條件為真時立即返回。

為什么

提高代碼可讀性

怎么做
摘抄一個《重構》中的栗子:
一個薪冊系統,以特殊來處理死亡、駐外、退休員工的薪資。

function getPayAmount() {
  let result;

  if (isDead) {
    result = deadAmount();
  }else{
    if(isSeparated) {
      result = separatedAmount();
    }else {
      if(isRetired) {
        result = retiredAmount()
      }else {
        result = normalAmount();
      }
    }
  }

  return result;
}

額額額,我覺得很少人會寫出這樣的代碼吧,很羅嗦,來看看重構后的代碼

function getPayAmount() {
  if (isDead)    return deadAmount();
  if (isSeparated)return separatedAmount();
  if (isRetired)return retiredAmount();
  
  return normalAmount();
}

雖然我們寫代碼不會像第一種那樣繁瑣,但使用衛語句我們可以讓代碼的可讀性大大提高,并提高代碼的效率(遇到 return 就結束,不會再向下執行)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1 Decompose Conditional(分解條件表達式) 從復雜表達式if-then-else三個段落中分...
    hklbird閱讀 1,468評論 0 0
  • 簡化條件表達式 9.1 Decompose Conditional (分解條件表達式) 你有一個復雜的條件表達式語...
    rxdxxxx閱讀 504評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,282評論 25 708
  • 今天早上,簡單的breakfast。昨晚做的全麥面包,想給孩子做個漂亮點的造型,貌似模具不是很給力。后來又...
    菩提釋閱讀 285評論 0 3
  • 國慶八天,幾乎都宅在婆婆家,這次回去,婆婆的態度似乎又好些,估摸著她也覺得我們也就呆幾天,所以放寬了標準,也...
    愛自滿溢閱讀 303評論 0 0