設計模式1:Builder構建器模式

帶着應用場景去學構建器設計模式

本文從代碼編寫中遇見的常見問題:如何優雅的設計需要大量參數的類?來由淺入深的學習構建器設計模式。

引經據典

遇到多個構造器參數時要考慮用構建器。

——《Effective Java》第二版

場景

設計一個表示食品營養成分的類,該類有必要的參數:每份含量、每份所含卡路里,以及其他非必須的參數:總脂肪量、飽和脂肪量、膽固醇及鈉的含量。

在設計類時因爲參數衆多,所以有編碼經驗的同學可以立即想到使用重疊的構造函數來設計:先寫一個包含必須參數的構造函數,然後寫重載函數幷包含一個非必須參數並調用包含必須參數的構造函數,然後再寫一個包含兩個非必須參數的構造函數…

這樣就得到了一個可以在創建時根據需要傳入非必須參數的類,優點是思路清晰,缺點也很明顯,如果這個類包含20個、30個參數時,將極大的增加編碼量,而且在客戶端實例化時,也並非可以簡潔清晰的創建所需的類。

結論:重疊的構造器可行,但是當參數很多時,客戶端代碼會很難編寫,並且難以閱讀。

嘗試使用JavaBean模式

聽起來高大上,其實就是通過無參構造器實例化之後按需調用setter來設置屬性值。

這種方式優點是比較直觀,無論是類的編寫還是客戶端實例化都可以很方便的實現,但是帶來很嚴重的缺陷就是,創建的類會處於中間狀態而帶來安全問題,當使用對象時,無法確保這個對象的參數是否全部設置好了。

在構建的過程中JavaBean可能處於不一致的狀態。 類無法通過檢驗構造器參數來保證一致性,在高併發場景下,如果使用了處於不一致狀態的對象,會帶來運行結果的錯誤,而且無法重新和排查。

Builder模式

通過上面的解決方案我們發現,構建過程的複雜性和代碼的可讀性、可維護性是最大的疑難點。我們可以試想,如果將構建過程抽離出來,提供簡潔的方法供使用者構建,然後返回構建的結果,如果採用這種實現方式,類的一致性和構建過程的簡潔性就得到了保證。

既能保證像重疊構造器模式的安全性,又能保證JavaBean模式的可讀性,這就是Builder模式

不直接生成想要的對象,而是讓客戶端利用所有必要的參數調用構造器(或者靜態工廠),得到一個builder對象。然後客戶端通過類似setter的調用將可選參數設置進去,最後通過build來生成最終對象。

我們先直接來看實現後的實例化過程

 NutritionFacts cocacola = new NurtritionFacts.Builder(240,16)
 											.calories(25)
 											.carbohydrate(27)
 											.build();

整個代碼簡潔清爽,這就是設計模式的魅力。

代碼實現

//TODO 預計2020/05/14 更新

實際應用中的注意事項

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章