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