抽象工廠模式(Abstract Factory)- 最易懂的設計模式解析
前言
在上文提到的 最易懂的設計模式系列解析:工廠方法模式 ,發現工廠方法模式存在一個嚴重的問題:
- 一個具體工廠只能建立一類產品
而在實際過程中,一個工廠往往需要生產多類產品。為了解決上述的問題,我們又使用了一種新的設計模式:抽象工廠模式。
目錄

1.jpg
1. 介紹
1.1 定義
抽象工廠模式,即Abstract Factory Pattern,提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類;具體的工廠負責實現具體的產品例項。
抽象工廠模式與工廠方法模式最大的區別:抽象工廠中每個工廠可以建立多種類的產品;而工廠方法每個工廠只能建立一類
1.2 主要作用
允許使用抽象的介面來建立一組相關產品,而不需要知道或關心實際生產出的具體產品是什麼,這樣就可以從具體產品中被解耦。
1.3 解決的問題
每個工廠只能建立一類產品
即工廠方法模式的缺點
2. 模式原理
2.1 UML類圖

944365-5d5b65294ac19246.png
2.2 模式組成

image.png
2.3 使用步驟
步驟1: 建立抽象工廠類,定義具體工廠的公共介面;
步驟2: 建立抽象產品族類 ,定義抽象產品的公共介面;
步驟3: 建立抽象產品類 (繼承抽象產品族類),定義具體產品的公共介面;
步驟4: 建立具體產品類(繼承抽象產品類) & 定義生產的具體產品;
步驟5:建立具體工廠類(繼承抽象工廠類),定義建立對應具體產品例項的方法;
步驟6:客戶端通過例項化具體的工廠類,並呼叫其建立不同目標產品的方法建立不同具體產品類的例項
3. 例項講解
接下來我用一個例項來對抽象工廠模式進行更深一步的介紹。
3.1 例項概況
·背景:小成有兩間塑料加工廠(A廠僅生產容器類產品;B廠僅生產模具類產品);隨著客戶需求的變化,A廠所在地的客戶需要也模具類產品,B廠所在地的客戶也需要容器類產品;
·衝突:沒有資源(資金+租位)在當地分別開設多一家注塑分廠
·解決方案:在原有的兩家塑料廠裡增設生產需求的功能,即A廠能生產容器+模具產品;B廠間能生產模具+容器產品。
即抽象工廠模式
3.2 使用步驟
步驟1: 建立抽象工廠類,定義具體工廠的公共介面
abstract class Factory{ public abstract Product ManufactureContainer(); public abstract Product ManufactureMould(); }
步驟2: 建立抽象產品族類 ,定義具體產品的公共介面;
abstract class AbstractProduct{ public abstract void Show(); }
步驟3: 建立抽象產品類 ,定義具體產品的公共介面;
//容器產品抽象類 abstract class ContainerProduct extends AbstractProduct{ @Override public abstract void Show(); } //模具產品抽象類 abstract class MouldProduct extends AbstractProduct{ @Override public abstract void Show(); }
步驟4: 建立具體產品類(繼承抽象產品類), 定義生產的具體產品;
//容器產品A類 class ContainerProductA extends ContainerProduct{ @Override public void Show() { System.out.println("生產出了容器產品A"); } } //容器產品B類 class ContainerProductB extends ContainerProduct{ @Override public void Show() { System.out.println("生產出了容器產品B"); } } //模具產品A類 class MouldProductA extends MouldProduct{ @Override public void Show() { System.out.println("生產出了模具產品A"); } } //模具產品B類 class MouldProductB extends MouldProduct{ @Override public void Show() { System.out.println("生產出了模具產品B"); } }
步驟5:建立具體工廠類(繼承抽象工廠類),定義建立對應具體產品例項的方法;
//A廠 - 生產模具+容器產品 class FactoryA extends Factory{ @Override public Product ManufactureContainer() { return new ContainerProductA(); } @Override public Product ManufactureMould() { return new MouldProductA(); } } //B廠 - 生產模具+容器產品 class FactoryB extends Factory{ @Override public Product ManufactureContainer() { return new ContainerProductB(); } @Override public Product ManufactureMould() { return new MouldProductB(); } }
步驟6:客戶端通過例項化具體的工廠類,並呼叫其建立不同目標產品的方法建立不同具體產品類的例項
//生產工作流程 public class AbstractFactoryPattern { public static void main(String[] args){ FactoryA mFactoryA = new FactoryA(); FactoryB mFactoryB = new FactoryB(); //A廠當地客戶需要容器產品A mFactoryA.ManufactureContainer().Show(); //A廠當地客戶需要模具產品A mFactoryA.ManufactureMould().Show(); //B廠當地客戶需要容器產品B mFactoryB.ManufactureContainer().Show(); //B廠當地客戶需要模具產品B mFactoryB.ManufactureMould().Show(); } }
結果:
生產出了容器產品A 生產出了容器產品B 生產出了模具產品A 生產出了模具產品B
4. 優點
降低耦合
抽象工廠模式將具體產品的建立延遲到具體工廠的子類中,這樣將物件的建立封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統耦合度低,這樣更有利於後期的維護和擴充套件;
更符合開-閉原則
新增一種產品類時,只需要增加相應的具體產品類和相應的工廠子類即可
簡單工廠模式需要修改工廠類的判斷邏輯
符合單一職責原則
每個具體工廠類只負責建立對應的產品
簡單工廠中的工廠類存在複雜的switch邏輯判斷
不使用靜態工廠方法,可以形成基於繼承的等級結構。
簡單工廠模式的工廠類使用靜態工廠方法
5. 缺點
抽象工廠模式很難支援新種類產品的變化。
這是因為抽象工廠介面中已經確定了可以被建立的產品集合,如果需要新增新產品,此時就必須去修改抽象工廠的介面,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發——封閉”原則。
對於新的產品族符合開-閉原則;對於新的產品種類不符合開-閉原則,這一特性稱為開-閉原則的傾斜性。
6. 應用場景
在瞭解了優缺點後,我總結了工廠方法模式的應用場景:
- 一個系統不要求依賴產品類例項如何被建立、組合和表達的表達,這點也是所有工廠模式應用的前提。
- 這個系統有多個系列產品,而系統中只消費其中某一系列產品
- 系統要求提供一個產品類的庫,所有產品以同樣的接口出現,客戶端不需要依賴具體實現。