天天看點

為啥你寫的代碼老有大串的if/else?

摘要:控制語句,到底何錯之有呢?

本文分享自華為雲社群《業務代碼如何才能不再寫出大串的if/else?》,作者: JavaEdge 。

控制結構?沒錯!你最愛的 if、for都是一類壞味道,沒想到吧?自己竟然每天都沉浸在寫壞味道的體驗中。

控制語句,到底何錯之有呢?

嵌套代碼

CR 如下分發我剛寫完的一篇部落格的案例:

為啥你寫的代碼老有大串的if/else?

邏輯很簡單,但有多層縮進,for 循環一層,裡面有倆 if ,又多加兩層。若邏輯再複雜點,縮進豈不是像啤酒肚一般越來越大?

為啥代碼會寫成這鬼樣子呢?

因為你在寫流水賬,如機器人般地按需求一步步翻譯成代碼。

代碼邏輯肯定沒錯,但功能實作後,未重新整理代碼。

現在就得消除縮進。

從for循環入手,通常for循環處理集合,而循環裡處理的是該集合中的元素。是以,可将循環中的内容提取成方法,隻處理一個元素:

為啥你寫的代碼老有大串的if/else?

這就是一次拆分,分解出來事務 issueArticle 每次隻處理一個元素。這就優化了縮進問題:

  • issueArticles 隻有一層縮進,這才是正常方法應有的樣子。
  • 但 issueArticle 還殘留多層縮進,待繼續優化。

if 和 else

issueArticle 裡,造成縮進的原因是 if 語句。if 縮進很多時候都是在檢查某先決條件,條件通過時,才能執行後續代碼。

這樣的代碼可使用衛語句(guard clause),即設定單獨檢查條件,不滿足該檢查條件時,方法立刻傳回。

以衛語句取代嵌套的條件表達式(Replace Nested Conditional with Guard Clauses)。

重構後的 issueArticle 函數:

為啥你寫的代碼老有大串的if/else?

如今這就隻剩一層縮進,代碼複雜度大大降低,可讀性和可維護性也大大增強。

禁用else

大多數人印象中,if 和 else 幾乎比翼齊飛。

else 可以不寫嗎?

可以!

根據文章資訊進行收費:

為啥你寫的代碼老有大串的if/else?

不用 else,簡單方式就是讓每個邏輯提前傳回,類似衛語句:

為啥你寫的代碼老有大串的if/else?

業務簡單的代碼,這重構還很輕松,但對複雜代碼,就得上多态了。

嵌套、else 語句,都是壞味道,本質上都在追求簡單,因為一段代碼的分支過多,其複雜度就會大幅度增加。

衡量代碼複雜度常用的标準,圈複雜度(Cyclomatic complexity,CC),CC越高,代碼越複雜,了解和維護的成本越高。

在CC判定中,循環和選擇語句占主要地位。CC可使用工具檢查,如Checkstyle,可限制最大的圈複雜度,當圈複雜度大于設定門檻值,就報錯。

重複 Switch

為啥你寫的代碼老有大串的if/else?

實際支付的價格會根據使用者在系統中的使用者級别有所差異,級别越高,折扣越高。

兩個函數裡出現了類似的代碼,其中最類似部分就是 switch,都據使用者級别判斷。

這并非僅有的根據使用者級别進行判斷的代碼,各種需區分使用者級别場景都有類似代碼,而這也是一種典型的壞味道:重複switch(Repeated Switch),通常都是因為缺少一個模型。

解決方案:以多态取代條件表達式(Relace Conditional with Polymorphism)。

引入 UserLevel 模型,消除 switch:

為啥你寫的代碼老有大串的if/else?

前面代碼即可去掉 switch:

為啥你寫的代碼老有大串的if/else?

switch 其實就是一堆“ if…else” 的簡化寫法,二者等價,是以,這個重構手法,以多态取代的是條件表達式,而不僅是取代 switch。

點選關注,第一時間了解華為雲新鮮技術~