設計模式筆記(四)--工廠方法模式、抽象工廠模式

工廠模式(Factory Pattern)

    (1)簡單工廠(Simple Factory)

應該都注意到了,這裏沒有使用模式(Pattern)的字眼,因爲簡單工廠更像是一種編程習慣,而不是嚴格意義上的設計模式。

先說一下客戶類怎麼使用:直接Pizza pizza = PizzaFactory.createPizza("cheese");就可以獲得CheesePizza類型的披薩了(PizzaFactory的靜態方法createPizza()中僅僅return new CheesePizaa();而已)。

再看一下涉及的角色:

工廠類角色:具體類,有一個根據不同參數創建不同對象的靜態方法(也就是上面的createPizza),並返回該對象父類型對象。

抽象產品角色:接口/抽象類,是所有產品的抽象(就是Pizza)。

具體產品角色:具體類,是工廠中要new的具體對象(就是CheesePizza)。

簡單點說,就是把創建對象的任務獨立出來,讓一個專門的類去負責創建,我們只需告訴這個類要創建對象的類型就能拿到該類型的對象了。

    (2)工廠方法模式(Factory Method Pattern)

定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個,工廠方法讓類把實例化推遲到子類。


其中的“工廠方法”就是用來實例化具體產品的。

這樣,原本由一個對象負責所有具體類的實例化,現在由一羣子類來實例化了。

在客戶類中我們可以看到:Pizza pizza = createPizza(type); ...  protected abstract Pizza createPizza(String type);實例化Pizza的責任被移到一個“方法中”,還是一個沒有實現的方法(由子類實現),該方法就像是一個“工廠”,可以創建對象,在超類中我們可以直接利用這個方法的返回對象,而不用管這個對象的具體實例化類型。

這樣,客戶程序(超類)的代碼和子類創建對象的代碼就解耦了。

Notes:

依賴倒置原則:要依賴抽象,不要依賴具體類

避免違反依賴倒置原則:①變量不要持有具體類的引用(不能直接new) ②不要派生自具體類(最好派生抽象) ③不要覆蓋基類中已經實現的方法

    (3)抽象工廠模式(Abstract Factory Pattern)

提供一個接口,用於創建相關或依賴對象的家族,而不需要指定具體類。

簡單點說,就是定義一個抽象的工廠類,其不同子類生產不同的產品族的產品。如果還不懂,下面的類圖可以便於理解。


用抽象的接口來創建一組相關的產品,這就是抽象工廠模式的目的。

先說一下背景:一個披薩(Pizza)店需要創建一個Pizza,當然Pizza是多種多樣的。首先Pizza說我需要一個原料工廠來創建我需要的原料,而原料又分爲麪糰、醬料、蔬菜肉等等,而麪糰又可分爲薄的和厚的,醬料也分大蒜番茄醬和李子形番茄醬等等。位於紐約的原料工廠只生產符合紐約人口味的薄面團和大蒜番茄醬原料,位於芝加哥的原料工廠也只生產芝加哥口味的厚麪糰和李形番茄醬原料。而對於一個具體的Pizza,當我需要原料時我就從原料工廠中拿就行了,我不關心具體是哪個原料工廠,我只關心怎麼製作Pizza(準備、烘烤、切片、裝箱)。這裏Pizza和具體原料就解耦了,是不是很帥啊。

對於客戶,如紐約Pizza店,要製作Pizza,先要有一個原料工廠來供應原料,它當然選擇紐約風味Pizza原料工廠作爲自己的Pizza原料工廠,然後就可以利用這個原料工廠創建比如芝士Pizza等不同Pizza了。

還要了解兩個概念:“產品等級結構”和“產品族”。產品等級結構是指不同產品的層次結構,例如這裏的厚麪糰和薄面團是相同的等級結構,大蒜番茄醬和李子形番茄醬也是相同的等級結構,但麪糰和番茄就是不同的等級結構了。產品族是指位於不同產品等級中功能相關聯的產品組成的家族,例如這裏的薄面團和大蒜番茄醬組成了紐約風味原料家族,而厚麪糰和李形番茄醬組成了芝加哥風味原料家族。所以每個具體工廠創建一組產品族產品。從抽象工廠派生出的具體工廠生產相同的產品,但是產品的實現不同。

    最後,還是要比較一下工廠方法模式和抽象工廠模式:

都是負責創建對象,將客戶從具體類型中解耦。

工廠方法用的是繼承,而抽象工廠用的是對象組合。

工廠方法是創建一個產品,而抽象工廠是創建整個產品家族。



發佈了48 篇原創文章 · 獲贊 168 · 訪問量 56萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章