天天看點

設計模式-工廠模式

一 工廠模式介紹

1.1 工廠模式的定義

先來看下GOF為工廠模式的定義:

“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”(在基類中定義建立對象的一個接口,讓子類決定執行個體化哪個類。工廠方法讓一個類的執行個體化延遲到子類中進行。)

1.2 工廠模式的分類:

1)簡單工廠(Simple Fatory)模式,又稱為靜态工廠方法模式(Static Factory Method Pattern)。

2)工廠方法(Factory Method)模式,又稱多态性工廠(Polymorphic Factory)模式或虛拟構造子(Virtual Constructor)模式;

3)抽象工廠(Abstract Factory)模式,又稱工具箱(Kit 或Toolkit)模式。

舉兩個比較常見的例子(我暫時可以準确想到的,當然還有很多很多):

 1)Spring中通過getBean("xxx")擷取Bean;

2)Java消息服務JMS中(下面以消息隊列ActiveMQ為例)

關于消息隊列ActiveMQ的使用可以檢視:消息隊列ActiveMQ的使用詳解

 1.4 為什麼要用工廠模式

1)解耦:把對象的建立和使用的過程分開

2)降低代碼重複:如果建立某個對象的過程都很複雜,需要一定的代碼量,而且很多地方都要用到,那麼就會有很多的重複代碼。

3)降低維護成本:由于建立過程都由工廠同一管理,是以發生業務邏輯變化,不需要找到所有需要建立對象B的地方去逐個修正,隻需要在工廠裡修改即可,降低維護成本。

二 簡單工廠模式

2.1 介紹

嚴格地說,簡單工廠模式并不是23種常用的設計模式之一,它隻算工廠模式的一個特殊實作。簡單工廠模式在實際中的應用相對于其他2個工廠模式用的還是相對少得多,因為它隻适應很多簡單的情況。

最重要的是它違背了我們在概述中說的開放-封閉原則(雖然可以通過反射機制來避免,後面我們會介紹到)。因為每次你要新添加一個功能,都需要再生

switch-case語句(或者if-else語句)中去修改代碼,添加分支條件。

2.2 适用場景

1)需要建立的對象較少

2)用戶端不關心對象的建立過程

2.3簡單工廠模式角色配置設定

1. 工廠(Factory)角色:簡單工廠模式的核心,它負責實作建立所有執行個體的内部邏輯。工廠類可以被外界直接調用,建立所需的産品對象。

2.抽象産品(Product)角色:簡單工廠模式所建立的所有對象的父類

3.具體産品(Concrete Product)角色:簡單工廠模式的建立目标,所有建立的對象都是充當這個角色的某個具體類的執行個體。

2.4 簡單工廠執行個體

建立一個可以繪制不同形狀的繪圖工具,可以繪制圓形、正方形、三角形,每個圖形都會有一個draw()方法用于繪圖。

1)建立shape接口

2)建立實作該接口的具體圖形類

圓形

長方形

正方形

3)建立工廠類

4)測試方法:

輸出結果:

這樣的實作有個問題,如果我們新增産品類的話,就需要修改工廠類中的getShape()方法,這很明顯不符合 開放-封閉原則 。

将工廠類改為下面的形式:

測試:

這種方式的雖然符合了 開放-關閉原則 ,但是每一次傳入的都是産品類的全部路徑,這樣比較麻煩。如果需要改善的話可以通過 反射+配置檔案 的形式來改善,這種方式使用的也是比較多的。

3 工廠方法模式

3.1 介紹

工廠方法模式應該是在工廠模式家族中是用的最多模式,一般項目中存在最多的就是這個模式。

工廠方法模式是簡單工廠的僅一步深化, 在工廠方法模式中,我們不再提供一個統一的工廠類來建立所有的對象,而是針對不同的對象提供不同的工廠。也就是說 每個對象都有一個與之對應的工廠 。

3.2 适用場景

一個類不知道它所需要的對象的類:在工廠方法模式中,用戶端不需要知道具體産品類的類名,隻需要知道所對應的工廠即可,具體的産品對象由具體工廠類建立;用戶端需要知道建立具體産品的工廠類。

一個類通過其子類來指定建立哪個對象:在工廠方法模式中,對于抽象工廠類隻需要提供一個建立産品的接口,而由其子類來确定具體要建立的對象,利用面向對象的多态性和裡氏

将建立對象的任務委托給多個工廠子類中的某一個,用戶端在使用時可以無需關心是哪一個工廠子類建立産品子類,需要時再動态指定,可将具體工廠類的類名存儲再配置檔案或資料庫中。

3.3 工廠方法模式角色配置設定:

抽象工廠(Abstract Factory)角色:是工廠方法模式的核心,與應用程式無關。任何在模式中建立的對象的工廠類必須實作這個接口。

具體工廠(Concrete Factory)角色 :這是實作抽象工廠接口的具體工廠類,包含與應用程式密切相關的邏輯,并且受到應用程式調用以建立某一種産品對象。

抽象産品(AbstractProduct)角色 :工廠方法模式所建立的對象的超類型,也就是産品對象的共同父類或共同擁有的接口。

具體産品(Concrete Product)角色 :這個角色實作了抽象産品角色所定義的接口。某具體産品有專門的具體工廠建立,它們之間往往一一對應

(1)增加一個工廠接口:

(2)增加相關工廠類:

圓形工廠類

長方形工廠類

(3)測試:

輸出:

在工廠方法模式中,其實我們有一個潛在意識的意識。那就是我們生産的都是同一類産品。抽象工廠模式是工廠方法的僅一步深化,在這個模式中的工廠類不單單可以建立一種産品,而是可以建立一組産品。

抽象工廠應該是比較最難了解的一個工廠模式了。

和工廠方法一樣用戶端不需要知道它所建立的對象的類。

需要一組對象共同完成某種功能時,并且可能存在多組對象完成不同功能的情況。(同屬于同一個産品族的産品)

系統結構穩定,不會頻繁的增加對象。(因為一旦增加就需要修改原有代碼,不符合開閉原則)

4.3 抽象工廠方法模式角色配置設定:

抽象工廠(AbstractFactory)角色 :是工廠方法模式的核心,與應用程式無關。任何在模式中建立的對象的工廠類必須實作這個接口。

具體工廠類(ConreteFactory)角色 :這是實作抽象工廠接口的具體工廠類,包含與應用程式密切相關的邏輯,并且受到應用程式調用以建立某一種産品對象。

抽象産品(Abstract Product)角色 :工廠方法模式所建立的對象的超類型,也就是産品對象的共同父類或共同擁有的接口。

具體産品(Concrete Product)角色 :抽象工廠模式所建立的任何産品對象都是某一個具體産品類的執行個體。在抽象工廠中建立的産品屬于同一産品族,這不同于工廠模式中的工廠隻建立單一産品,我後面也會詳解介紹到。

繼續閱讀