開閉原則的一點感觸
在程式碼裡直接加一個邏輯分支的誘惑力,有時候可能是局外人難以想象的,就像夏天吃小龍蝦時候的喝的冰可樂,美味卻代價昂貴(一瓶可樂半瓶糖~)。以至於最近在做Code Review的時候,發現有一段程式碼裡差不多有10個邏輯分支。
其實以前團隊是有個不成文的“競賽”的:
比誰在程式碼裡寫的if
少。
比如業務裡有多組定價策略。一開始可能就這麼寫了。
if (strategy == Prince.StrategyA) { … } else if (strategy == Prince.StrategyB) { … } else { … }
如果再來一種策略就再加個分支。其實把各個策略通過多型封裝在各自的實現類裡,並把實現類“註冊”到分發器(Dispatcher)裡可以實現的稍微優雅一點。
public class Dispatcher { Map<String, PrinceStrategy> strategies; … // 分發執行 PrinceStrategy princeStrategy = strategies.get(strategy) priceStrategy.doPrincing() }
開頭提到的10多個邏輯分支的場景,其實是因為任務狀態從一開始的3個慢慢的膨脹,而每次的應對方式都是在原來的程式碼裡面增加一小段分支。其實是一種很適合用狀態機模式重構的場景。
從表面看,無論方式,程式碼還是哪些程式碼,只是拆分到了不同類裡。
但是最近突然有點感悟:其實這兩種方式更側重於為了滿足“開閉原則”:當需要實現拓展的時候,對於原來的程式碼基本上不需要進行改動,造成的風險更小,測試迴歸的成本自然也就更低。