設計模式 —— 抽象工廠模式
在瞭解抽象工廠模式之前,我們必須先了解一個概念 產品族 。所謂的 產品族 :是指位於不同產品等級結構中,功能相關聯的產品組成的家族。
舉個例子:在肥宅心中除了快樂水最喜歡的就是動漫了。

在上面的圖中,熱血番和搞笑番稱為兩個不同的等級結構;而國產動漫和日本動漫則稱為兩個不同的產品族。具體點就是。國漫的熱血番和日漫的熱血番屬於同一等級結構,國漫的搞笑番和日漫的搞笑番屬於同一等級結構;國漫熱血番和國漫搞笑番屬於同一產品族,日漫熱血番和日漫搞笑番屬於同一產品族。
明白了等級結構和產品族的概念,我們來看抽象工廠的定義: 抽象工廠模式 (Abstract Factory Pattern)是為建立一組相關或相互依賴的物件提供一個介面,而且無需指定他們的具體類。
例項
就以動漫為例子:
產品介面定義:
// 熱血番劇 public interface BloodDrama { String name(); } // 搞笑番劇 public interface FunnyDrama { String name(); } 複製程式碼
產品具體實現:
// 中國熱血番 public class ChinaBloodDrama implements BloodDrama { @Override public String name() { return "中國熱血番"; } } // 中國搞笑番 public class ChinaFunnyDrama implements FunnyDrama { @Override public String name() { return "中國搞笑番"; } } //日本熱血番 public class JapanBloodDrama implements BloodDrama { @Override public String name() { return "日本熱血番"; } } //日本搞笑番 public class JapanFunnyDrama implements FunnyDrama { @Override public String name() { return "日本搞笑番"; } } 複製程式碼
工廠介面定義:
public interface Factory { BloodDrama createBloodDrama(); FunnyDrama createFunnyDrama(); } 複製程式碼
工廠具體實現:
// 國漫工廠 public class ChinaAnimeFactory implements Factory { @Override public BloodDrama createBloodDrama() { return new ChinaBloodDrama(); } @Override public FunnyDrama createFunnyDrama() { return new ChinaFunnyDrama(); } } // 日漫工廠 public class JapanAnimeFactory implements Factory { @Override public BloodDrama createBloodDrama() { return new JapanBloodDrama(); } @Override public FunnyDrama createFunnyDrama() { return new JapanFunnyDrama(); } } 複製程式碼
客戶端(肥宅):
public class Fz { @Test public void watch() { // 國漫工廠 Factory chinaAnimeFactory = new ChinaAnimeFactory(); System.out.println("肥宅觀看:" + chinaAnimeFactory.createBloodDrama().name()); System.out.println("肥宅觀看:" + chinaAnimeFactory.createFunnyDrama().name()); // 日漫工廠 Factory japanAnimeFactory = new JapanAnimeFactory(); System.out.println("肥宅觀看:" + japanAnimeFactory.createBloodDrama().name()); System.out.println("肥宅觀看:" + japanAnimeFactory.createFunnyDrama().name()); } } 複製程式碼
類圖

優點
-
具有工廠方法模式的優點外;
-
在類內部對產品族的關聯關係進行定義和描述,而不必專門引入一個新的類來進行管理;
-
當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。
缺點
產品族的擴充套件將是一件十分費力的事情,假如產品族中需要增加一個新的產品,則幾乎所有的工廠類都需要進行修改。例如上面例子擴充套件一個 治癒番 。所以使用抽象工廠模式時,對產品等級結構的劃分是非常重要的。
適用場景
當需要建立的物件是一系列相互關聯或相互依賴的產品族時,便可以使用抽象工廠模式。例如 系統日誌記錄 :可能儲存到資料庫、本地檔案、快取、遠端伺服器等,使用者可以自己選擇記錄方式。
總結
無論是簡單工廠模式,工廠方法模式,還是抽象工廠模式,他們都屬於工廠模式,在形式和特點上也是極為相似的,他們的最終目的都是為了解耦。在使用時,我們不必去在意這個模式到底工廠方法模式還是抽象工廠模式,因為他們之間的演變常常是令人琢磨不透的。經常你會發現,明明使用的工廠方法模式,當新需求來臨,稍加修改,加入了一個新方法後,由於類中的產品構成了不同等級結構中的產品族,它就變成抽象工廠模式了;而對於抽象工廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了工廠方法模式。所以,在使用工廠模式時,只需要關心降低耦合度的目的是否達到了。