天天看點

再寫if-else,逮着罰款1000

本文并不肯定或者否定哪一種寫法,僅僅為大家提供一些其他的編碼思路或者一些值得借鑒的點子。

再寫if-else,逮着罰款1000

設計更好的軟體,替換 If-Else 的 5 種方法,從入門到進階示例

If-Else 通常是一個糟糕的選擇,它導緻設計複雜,代碼可讀性差,并且可能導緻重構困難。

但是,If-Else 已成為事實上的代碼分支解決方案,這确實是有道理的。這是向所有有抱負的開發人員講授的第一件事。

不幸的是,許多開發人員從來沒有前進到更合适的分支政策。有些人的口頭禅是:If-Else 是一把錘子,一切都是釘子。

我将向大家展示一些技巧和模式,這些技巧和模式将終結這種可怕的做法。每個示例的難度都會增加。

# 完全不必要的 Else 塊

這也許是那些初級開發人員最負罪的之一。下面的示例很好地說明了當你被認為 If-Else 很棒時會發生什麼:

再寫if-else,逮着罰款1000

Simple if-else

隻需删除 else` 塊即可簡化此過程,如下圖:

再寫if-else,逮着罰款1000

Removed else

看起來更專業吧?你會發現,實際上根本不需要其他塊。像在這種情況下一樣,你想要在滿足特定條件的情況下執行某些操作并立即傳回。

價值配置設定

如果你要根據提供的某些輸入為變量配置設定新值,請停止 If-Else 廢話,一種更具可讀性的方法。

再寫if-else,逮着罰款1000

Value assignment with if-else

盡管很簡單,但它卻很糟糕。首先,If-Else 很容易在這裡被開關取代。但是,我們可以通過完全删除 else 來進一步簡化此代碼。

再寫if-else,逮着罰款1000

If statements with fast return

如果不使用 else,則我們将剩下幹淨的可讀代碼。請注意,我也将樣式更改為快速傳回而不是單傳回語句。如果已經找到正确的值,繼續測試一個值根本沒有意義。

# 前提條件檢查

通常,我發現,如果方法提供了無效的值,則繼續執行是沒有意義的。假設我們從以前就有了 DefineGender 方法,要求提供的輸入值必須始終為 0 或 1。

再寫if-else,逮着罰款1000

Method without value checks

在沒有價值驗證的情況下執行該方法沒有任何意義。是以,在允許方法繼續執行之前,我們需要檢查一些先決條件。

應用保護子句防禦性編碼技術,你将檢查方法的輸入值,然後繼續執行方法。

再寫if-else,逮着罰款1000

Check preconditions with guard clauses

至此,我們確定僅在值落在預期範圍内時才執行主邏輯。現在,IF 也已被三元代替,因為不再需要在結尾處預設傳回未知。

将 If-Else 轉換為字典,完全避免 If-Else

假設您需要執行一些操作,這些操作将根據某些條件進行選擇,我們知道以後必須添加更多操作。

再寫if-else,逮着罰款1000

也許有人傾向于使用久經考驗的 If-Else。如果添加新操作,則隻需簡單地添加其他内容即可。很簡單 但是,就維護而言,這種方法不是一個好的設計。

知道我們以後需要添加新的操作後,我們可以将 If-Else 重構為字典。

再寫if-else,逮着罰款1000

可讀性已大大提高,并且可以更輕松地推斷出該代碼。注意,僅出于說明目的将字典放置在方法内部。您可能希望從其他地方提供它。

擴充應用程式,完全避免使用 If-Else

這是一個稍微進階的示例。通過用對象替換它們,知道何時甚至完全消除 If。

通常,您會發現自己不得不擴充應用程式的某些部分。作為初級開發人員,您可能會傾向于通過添加額外的 If-Else(即 else-if)語句來做到這一點。

舉這個說明性的例子。在這裡,我們需要将 Order 執行個體顯示為字元串。首先,我們隻有兩種字元串表示形式:JSON 和純文字。

在此階段使用 If-Else 并不是什麼大問題,如果我們可以輕松替換其他,隻要如前所述即可。

再寫if-else,逮着罰款1000

知道我們需要擴充應用程式的這一部分,這種方法絕對是不可接受的。

上面的代碼不僅違反了打開/關閉原則,而且閱讀得不好,還會引起可維護性方面的麻煩。

正确的方法是遵循 SOLID 原則的方法,我們通過實施動态類型發現過程(在本例中為政策模式)來做到這一點。

重構這個混亂的過程的過程如下:

  • 使用公共接口将每個分支提取到單獨的政策類中。
  • 動态查找實作通用接口的所有類。
  • 根據輸入決定執行哪種政策。

替換上面示例的代碼如下所示。是的,這是更多代碼的方式。它要求您了解類型發現的工作原理。但是動态擴充應用程式是一個進階主題。

我隻顯示将替換 If-Else 示例的确切部分。如果要檢視所有涉及的對象,請檢視此要點。

再寫if-else,逮着罰款1000

讓我們快速浏覽一下代碼。方法簽名保持不變,因為調用者不需要了解我們的重構。

首先,擷取實作通用接口 IOrderOutputStrategy 的程式集中的所有類型。然後,我們建立一個字典,格式化程式的 displayName 的名稱為 key,類型為 value。

然後從字典中選擇格式化程式類型,然後嘗試執行個體化政策對象。最後,調用政策對象的 ConvertOrderToString。