你還在用if-else嗎?鮑勃大叔提出改進意見!

banq發表於2021-03-20

if/else/switch語句的泛濫是軟體系統中的常見問題。它們在許多地方被複制的事實是有問題的。
幾天前,有人在推特上發了一個問題,詢問以下哪個PHP片段更好,或者是否有更好的方法。

你還在用if-else嗎?鮑勃大叔提出改進意見!
我的建議是:將if / else放入一個工廠物件中,這個工廠是為每個變數建立一個多型物件。在“ main”中建立工廠並將其傳遞到您的應用中。這將確保if / else鏈僅出現一次。

if/else/switch語句存在一個更嚴重的問題。這是依賴結構。

你還在用if-else嗎?鮑勃大叔提出改進意見!
此類陳述傾向於將案例指向外部,指向較低階別的模組。這通常意味著包含的模組if/else/switch將依賴於那些較低階別的模組的原始碼。這些if/else/switch語句變成了依賴磁鐵,這些磁鐵吸引了大範圍的系統原始碼,從而將系統繫結到了緊密的整體式體系結構中,而沒有靈活的元件結構。
夠糟糕的。我們不喜歡從高階模組到低階模組的依賴關係。他們阻止了我們建立由可獨立部署的元件組成的體系結構的願望。
解決此問題的方法是打破那些對較低階別模組的向外依賴。這可以透過簡單的多型來完成。

你還在用if-else嗎?鮑勃大叔提出改進意見!
在上圖中,您可以看到使用基類介面的高階模組,該介面多型地部署到低階詳細資訊。稍加思考,您就應該能夠看出這與行為在本質上是相同的,if/else/switch但是有所不同。在那些高階策略模組呼叫基類介面之前,必須先確定要遵循哪種情況。
現在,僅檢視依賴關係的方向。從高階模組到低階模組不再有任何傳遞原始碼依賴性。我們可以輕鬆地建立一個將它們分開的元件邊界。我們甚至可以獨立於低層模組部署高層模組。這構成了令人愉悅的靈活體系結構。
要考慮的另一點是if/else/switch和的多型實現都使用表查詢來完成其工作。在if/else表的情況下,表查詢是過程性的。在switch大多數情況下,編譯器會建立一個小的查詢表。在多型排程的情況下,向量表被內建到基類介面中。因此,這三個都具有非常相似的執行時和記憶體特徵。一個並不比另一個快得多。
那麼,決策從何而來呢?當建立基類的例項時做出決定。希望創作發生在一個很好的安全地方,如main。通常,我們使用簡單的工廠類來管理它。

你還在用if-else嗎?鮑勃大叔提出改進意見!
在上圖中,您可以看到高階模組使用基類來完成其工作。曾經依賴於一條語句的每個業務規則,有其自己的特定方法來在基類中進行呼叫。當業務規則呼叫該方法時,它將部署到適當的低階模組。低階模組由Factory建立。
再次注意依賴關係的方向。看到那條紅線嗎?這是一個方便的元件邊界。所有依賴項都指向較高階別的模組。
高階模組呼叫傳遞表示決策的某種令牌的make(x)方法。請謹慎使用該令牌x。請勿嘗試使其成為需要在紅線上方進行宣告的enum 或任何其他內容。整數或字串是令牌x更好的選擇。它可能不是型別安全的。實際上,它不是型別安全的。但是,它將允許您保留體系結構的元件結構。
您可能會擔心另一件事。該基類需要為曾經依賴於if/else/switch決策的每個業務規則提供一種方法。隨著更多這些業務規則的出現,您將不得不向基類新增更多方法。而且由於許多業務規則已經依賴於基類,因此即使他們不關心任何更改,也必須重新編譯/重新部署它們。
有很多方法可以解決該問題。我可以繼續用這個部落格寫另外2,000個單詞,或者描述它們。為避免這種情況,我建議您查詢“介面隔離原理”和“非迴圈訪問者”模式。

 
相關:

鮑勃大爺:將if/else中每個條件變為邏輯並列互拆而不依賴執行順序。
 

幽默:當你的程式碼中有多個巢狀if-else語句時

banq 2006年的文章:你還在用if else嗎?https://www.jdon.com/artichect/ifelse.htm

相關文章