前面介紹的工廠方法模式中考慮的是一類產品的生產,如畜牧場只養動物、電視機廠只生產電視機、計算機軟件學院只培養計算機軟件專業的學生等。
同種類稱為同等級,也就是說:工廠方法模式只考慮生產同等級的產品,但是在現實生活中許多工廠是綜合型的工廠,能生產多等級(種類) 的產品,如農場里既養動物又種植物,電器廠既生產電視機又生產洗衣機或空調,大學既有軟件專業又有生物專業等。
抽象工廠模式將考慮多等級產品的生產,將同一個具體工廠所生產的位於不同等級的一組產品稱為一個產品族,下圖所示的是海爾工廠和 TCL 工廠所生產的電視機與空調對應的關系圖:
定義與特點
抽象工廠(AbstractFactory)模式的定義:是一種為訪問類提供一個創建一組相關或相互依賴對象的接口,且訪問類無須指定所要產品的具體類就能得到同族的不同等級的產品的模式結構。
抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。
使用抽象工廠模式一般要滿足以下條件:
- 系統中有多個產品族,每個具體工廠創建同一族但屬於不同等級結構的產品。
- 系統一次只可能消費其中某一族產品,即同族的產品一起使用。
抽象工廠模式除了具有工廠方法模式的優點外,其他主要優點如下:
- 可以在工廠類的內部對產品族中相關聯的多等級產品共同管理,而不必專門引入多個新的類來進行管理。
- 當增加一個新的產品族時不需要修改原代碼,滿足開閉原則。
其缺點是:當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。
結構與實現
抽象工廠模式同工廠方法模式一樣,也是由抽象工廠、具體工廠、抽象產品和具體產品等 4 個要素構成,但抽象工廠中方法個數不同,抽象產品的個數也不同。
模式的結構
抽象工廠模式的主要角色如下:
- 抽象工廠(Abstract Factory):提供了創建產品的接口,它包含多個創建產品的方法CreateProduct(),可以創建多個不同等級的產品。
- 具體工廠(Concrete Factory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的創建。
- 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
- 具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間是多對一的關系。
注:抽象工廠、抽象產品的定義推薦使用抽象類,GOF中也是使用的抽象類。
抽象工廠模式的簡化結構圖如圖所示(來自GOF):
抽象工廠模式的詳細結構圖如圖所示(1、2代表產品族,如海爾、TCL等;A、B代表產品等級,如電視機、空調等):
模式的實現
參考工廠方法的代碼實現,增加多個具體工廠、多個抽象產品,部分代碼如下:
/// <summary>
/// 抽象工廠類
/// </summary>
public abstract class AbstractFactory
{
public abstract ProductA CreatProduct();
public abstract ProductB CreatProduct();
}
/// <summary>
/// 具體工廠類A1
/// </summary>
public class ConcreteFactoryA1 : AbstractFactory
{
public override ProductA CreatProduct()
{
return new ConcreteProductA1();
}
public override ProductB CreatProduct()
{
return new ConcreteProductB1();
}
}
應用場景
抽象工廠模式最早的應用是用於創建屬於不同操作系統的視窗構件。如 java 的 AWT 中的 Button 和 Text 等構件在 Windows 和 UNIX 中的本地實現是不同的。
抽象工廠模式通常適用於以下場景:
- 當需要創建的對象是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。
- 系統中有多個產品族,但每次只使用其中的某一族產品。如有人只喜歡穿某一個品牌的衣服和鞋。
- 系統中提供了產品的類庫,且所有產品的接口相同,客戶端不依賴產品實例的創建細節和內部結構。
模式的擴展
抽象工廠模式的擴展有一定的“開閉原則”傾斜性:
- 當增加一個新的產品族時只需增加一個新的具體工廠,不需要修改原代碼,滿足開閉原則。
- 當產品族中需要增加一個新種類的產品時,則所有的工廠類都需要進行修改,不滿足開閉原則。
另一方面,當系統中只存在一個等級結構的產品時,抽象工廠模式將退化到工廠方法模式。