本篇文章介紹一種設計模式——工廠模式。工廠模式是用來封裝對象的創建,減少應用程序和具體類之間的依賴,促進松耦合。根據工廠模式的應用特性,一共分為三種子模式:簡單工廠模式,工廠方法模式和抽象工廠模式。本篇文章主要介紹抽象工廠模式。本篇文章內容參考抽象工廠模式,【原】從頭學習設計模式(四)——抽象工廠模式。
一、抽象工廠模式簡介
1.定義
抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬于對象創建型模式。
定義很難懂?沒錯,看起來是很抽象,不過這正反應了這種模式的強大。下面具體闡述下定義。
2.定義闡述
在工廠方法模式中具體工廠負責生產具體的產品,每一個具體工廠對應一種或幾種具體產品,工廠方法也具有唯一性,一般情況下,一個具體工廠中只有一個工廠方法或者一組重載的工廠方法。但是有時候我們需要一個工廠可以提供多個不同種類產品對象,而不是單一種類的產品對象。
為了更清晰地理解工廠方法模式,需要先引入兩個概念:
產品等級結構 :產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。
產品族 :在抽象工廠模式中,產品族是指由同一個工廠生產的,位于不同產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位于電視機產品等級結構中,海爾電冰箱位于電冰箱產品等級結構中。
當系統所提供的工廠所需生產的具體產品并不是一個簡單的對象,而是多個位于不同產品等級結構中屬于不同類型的具體產品時需要使用抽象工廠模式。
抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態。
抽象工廠模式與工廠方法模式最大的區別在于,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則需要面對多個產品等級結構,一個工廠等級結構可以負責多個不同產品等級結構中的產品對象的創建 。當一個工廠等級結構可以創建出分屬于不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更為簡單、有效率。
二、抽象工廠模式結構
1.模式結構
抽象工廠模式包含如下角色:
AbstractFactory:抽象工廠
ConcreteFactory:具體工廠
AbstractProduct:抽象產品
Product:具體產品
2.時序圖
①先調用具體工廠對象中的方法createProductX()。根據具體工廠不同可以選擇不同的方法,針對同一種工廠也可以選擇不同的方法創建不同類型的產品對象。
②根據傳入產品類型參數(也可以無參),獲得具體的產品對象
③返回產品對象并使用
三、抽象工廠的使用實例
假設有一個移動終端工廠,可以制造蘋果系列的移動產品和三星系列的移動產品。這個工廠下有兩個子廠,一個負責制造蘋果系列的Pad和三星系列的Pad,另一個負責制造蘋果系列的手機和三星系列的手機。這便是一個典型的抽象工廠的實例。
抽象產品: 蘋果系列
public interface Apple
{
void AppleStyle();
}
抽象產品: 三星系列
public interface Sumsung
{
void BangziStyle();
}
具體產品:iphone
public class iphone implements Apple
{
public void AppleStyle()
{
Console.WriteLine("Apple's style: iPhone!");
}
}
具體產品:ipad
public class ipad implements Apple
{
public void AppleStyle()
{
Console.WriteLine("Apple's style: iPad!");
}
}
具體產品:note2
public class note2 implements Sumsung
{
public void BangziStyle()
{
Console.WriteLine("Bangzi's style : Note2!");
}
}
具體產品:tabs
public class Tabs implements Sumsung
{
public void BangziStyle()
{
Console.WriteLine("Bangzi's style : Tab!");
}
}
抽象工廠
public interface Factory
{
Apple createAppleProduct();
Sumsung createSumsungProduct();
}
手機工廠
public class Factory_Phone implements Factory
{
public Apple createAppleProduct()
{
return new iphone();
}
public Sumsung createSumsungProduct()
{
return new note2();
}
}
pad工廠
public class Factory_Pad implements Factory
{
public Apple createAppleProduct()
{
return new ipad();
}
public Sumsung createSumsungProduct()
{
return new Tabs();
}
}
客戶端調用
public static void Main(string[] args)
{
//采購商要一臺iPad和一臺Tab
Factory factory = new Factory_Pad();
Apple apple = factory.createAppleProduct();
apple.AppleStyle();
Sumsung sumsung = factory.createSumsungProduct();
sumsung.BangziStyle();
//采購商又要一臺iPhone和一臺Note2
factory = new Factory_Phone();
apple = factory.createAppleProduct();
apple.AppleStyle();
sumsung = factory.createSumsungProduct();
sumsung.BangziStyle();
Console.ReadKey();
}
抽象工廠可以通過多態,來動態設置不同的工廠,生產不同的產品,同時每個工廠中的產品又不屬于同一個產品等級結構。
四、抽象工廠模式優缺點
優點
①抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創建。由于這種隔離,更換一個具體工廠就變得相對容易。所有的具體工廠都實現了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行為。另外,應用抽象工廠模式可以實現高內聚低耦合的設計目的,因此抽象工廠模式得到了廣泛的應用。
②增加新的具體工廠和產品族很方便,因為一個具體的工廠實現代表的是一個產品族,無須修改已有系統,符合“開閉原則”。
缺點
在添加新的產品對象(不同于現有的產品等級結構)時,難以擴展抽象工廠來生產新種類的產品,這是因為在抽象工廠角色中規定了所有可能被創建的產品集合,要支持新種類的產品就意味著要對該接口進行擴展,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
開閉原則的傾斜性(增加新的工廠和產品族容易,增加新的產品等級結構麻煩)。
適用環境
在以下情況下可以使用抽象工廠模式:
①一個系統不應當依賴于產品類實例如何被創建、組合和表達的細節,這對于所有類型的工廠模式都是重要的。
②系統中有多于一個的產品族,而每次只使用其中某一產品族。與工廠方法模式的區別
③屬于同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。
④系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴于具體實現。