聲明一: 本文
內容屬於《Head First 設計模式》閱讀筆記
,文中涉及到的知識案例等直接或間接來源於該書。《Head First 設計模式》
通過有趣的圖表+文字的形式,讓人自然學習設計模式,非常棒
,推薦閱讀
。
聲明二: 工廠模式使用靈活,在不同的情境下,可能有不同的表現形式。本文的重點在介紹工廠模式,而非使用工廠模式,所以在示例代碼中的一些地方作了簡化處理,更方便理解。在實際開發應用時,還可對示例中的代碼進一步優化(如:在類型上使用枚舉,而不使用字符串等)。
聲明三: 本文代碼部分全部以圖片的形式給出,如有需要,可直接去文末Github鏈接處下載測試項目。
概述:
工廠模式的設計出發點是對擴展開放,對修改關閉;常見的工廠模式可分爲簡單工廠、靜態工廠、工廠方法、抽象工廠;其中簡單工廠與靜態工廠可以說是一種基本的編程習慣,而工廠方法以及抽象工廠纔是工廠模式的重心。。
簡單工廠: 提供一個工廠類,通過給該工廠類相應的實例方法傳入不同的參數,來創建不同的對象。
示例:
- 情景介紹:
現有一家披薩店,這家披薩店製作披薩需要兩步:第一步,獲取到不同類型的生披薩;第二步,將生披薩進行準備(如加佐料等)、烘烤、切片、裝盒後,得到最終可食用的熟披薩。 - (生的)披薩類:
- (生的)披薩的實現有:
- 不使用工廠模式(的寫法):
- 使用工廠模式(的寫法):
- 編寫工廠類:
- 使用工廠類:
- 編寫工廠類:
靜態工廠: 提供一個工廠類,通過給該工廠類相應的靜態方法傳入不同的參數,來創建不同的對象(即:靜態工廠與簡單工廠幾乎一樣,只不過簡單工廠用的是實例方法,而靜態工廠用的是靜態方法)。
示例:
- 情景介紹:
現有一家披薩店,這家披薩店製作披薩需要兩步:第一步,獲取到不同類型的生披薩;第二步,將生披薩進行準備(如加佐料等)、烘烤、切片、裝盒後,得到最終可食用的熟披薩。 - (生的)披薩類:
- (生的)披薩的實現有:
- 不使用工廠模式(的寫法):
- 使用工廠模式(的寫法):
- 編寫工廠類:
- 使用工廠類:
- 編寫工廠類:
工廠方法:在抽象類中,定義一個抽象方法來獲取需要的對象,在常規方法裏使用這個對象編寫邏輯。不同的子類對該抽象方法進行不同的實現,來達到工廠的效果(,如果有必要,子類還可以重寫這個抽象類的其它方法)。
示例:
- 情景介紹:
現有全球連鎖披薩店,披薩店製作披薩需要兩步:第一步,獲取到不同類型的生披薩;第二步,將生披薩進行準備(如加佐料等)、烘烤、切片、裝盒後,得到最終可食用的熟披薩。且每個國家對同一種披薩可能有屬於自己國家的口味,如:Abc國的芝士披薩是這種味,Xyz國的芝士披薩是另一種味。 - (生的)披薩類:
- (生的)披薩的實現有:
- 對於Abc國以及Xyz國來說,可能有自己的生披薩實現:
- 不使用工廠模式(的寫法):
- 使用工廠模式(的寫法):
- 編寫抽象父類,定義工廠方法:
- 編寫子類,實現工廠方法:
- Abc國的子類實現:
- Xyz國的子類實現:
- Abc國的子類實現:
- 編寫抽象父類,定義工廠方法:
- 使用測試:
- 編寫測試類:
- 運行main方法,控制檯輸出:
- 編寫測試類:
抽象工廠:提供一個接口,用於獲得一系列相關的對象(即:用於獲得一組對象)。至於獲得到的這組對象是什麼樣子的,由抽象工廠的實現類決定。
示例:
-
情景介紹:
一個煎餅果子,需要的原料有面團、蔬菜、油條、腐乳、蔥花。現有一家連鎖的煎餅果子店,在Abc省以及Xyz省都有分店。但是Abc省與Xyz省,用的原料卻有差異。 -
從抽象工廠出發:
從【一個煎餅果子,需要的原料有面團、蔬菜、油條、腐乳、蔥花】可知:麪糰、蔬菜、油條、腐乳、蔥花都是煎餅果子原料,根據抽象工廠的概念,我們可以提供一個接口,用於獲得麪糰、蔬菜、油條、腐乳、蔥花。 -
設計:
-
抽象工廠與實現類:
-
煎餅果子基類與子類:
-
上述示例的關鍵代碼:
-
抽象工廠PancakeIngredientFactory:
-
抽象工廠實現類PancakeIngredientFactory:
注:XyzPancakeIngredientFactory類與AbcPancakeIngredientFactory類類似,這裏就不給出了。 -
煎餅果子基類BasePancake:
-
具有地方特色的煎餅果子類AbcPancake:
注:XyzPancake類與AbcPancake類類似,這裏就不給出了。
-
-
測試一下:
- 控制檯輸出:
- 控制檯輸出:
工廠模式學習完畢!
^_^ 如有不當之處,歡迎指正
^_^ 參考資料
《Head First 設計模式》Eric Freeman & Elisabeth Freeman with Kathy Sierra & Bert Bates著,O’Reilly Taiwan公司譯,UMLChina改編
^_^ 測試代碼託管鏈接
https://github.com/JustryDeng…DesignPattern
^_^ 本文已經被收錄進《程序員成長筆記(六)》,筆者JustryDeng