設計模式——抽象工廠模式(JAVA)
在抽象工廠模式中,一個具體工廠可以生產一組相關的具體產品,這樣的一組產品成爲產品族,產品族中的每一個產品都屬於某一個產品繼承等等級結構。當系統所提供的工廠生產的具體產品並不是一個簡單的對象,而是多個位於不同產品等級結構、屬於不同類型的具體產品時就可以使用抽象工廠模式。
抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式需要面對多個產品等級結構,一個工廠等級結構可以負責多個不同產品等級結構中的產品對象的創建,當一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更爲簡單、更有效率。
抽象工廠模式爲創建一組對象提供了一種解決方案。與工廠方法模式相比,抽象工廠模式中的具體工廠不只是創建一種產品,而是負責創建一組產品。
抽象工廠模式定義:提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。
一、抽象工廠模式的結構
在抽象工廠模式張,每一個具體工廠都提供了多個工廠方法用於產生多種不同類型的產品,這些產品構成一個產品族。
抽象工廠模式包含以下4個角色:
(1)AbstractFactory(抽象工廠):它聲明瞭一組用於創建一族產品的方法,每一個方法對應一種產品。
(2)ConcreteFactory(具體工廠):它實現了抽象工廠中聲明的創建產品的方法,生成一組具體產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。
(3)AbstractProduct(抽象產品):它爲每種產品聲明接口,在抽象產品中聲明瞭產品所具有的業務方法。
(4)ConcreteProduct(具體產品):它定義具體工廠生產的具體產品對象,它實現抽象產品接口中聲明的業務方法。
二、抽象工廠模式的實現
在抽象工廠中聲明瞭多個工廠方法,用於創建不同類型的產品,抽象工廠可以是接口,也可以是抽象類或具體類。
abstract class AbstractFactory
{
public abstract AbstractProduct CreateProduct(); //工廠方法
......
}
具體工廠實現了抽象工廠,每一個具體的工廠方法創建一個特定的產品對象,而同一個具體工廠所創建的產品對象構成了一個產品族。對於每一個具體工廠類:
class ConcreteFactory : AbstractFactory
{
//工廠方法
public override AbstractProduct CreateProduct()
{
return new ConcreteProduct();
}
......
}
與工廠方法模式一樣,抽象工廠模式也可以爲每一種產品提供一組重載的工廠方法,以不同的方式來創建產品對象。
三、抽象工廠模式的應用
在上面的類圖中,兩廂車和三廂車稱爲兩個不同的等級結構;而2.0排量車和2.4排量車則稱爲兩個不同的產品族。再具體一點,2.0排量兩廂車和2.4排量兩廂車屬於同一個等級結構,2.0排量三廂車和2.4排量三廂車屬於另一個等級結構;而2.0排量兩廂車和2.0排量三廂車屬於同一個產品族,2.4排量兩廂車和2.4排量三廂車屬於另一個產品族。
明白了等級結構和產品族的概念,就理解工廠方法模式和抽象工廠模式的區別了,如果工廠的產品全部屬於同一個等級結構,則屬於工廠方法模式;如果工廠的產品來自多個等級結構,則屬於抽象工廠模式。在本例中,如果一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那麼他屬於工廠方法模式瞭如果一個工廠模式提供2.4排量兩廂車和2.4排量三廂車兩個產品,那麼這個工廠模式就是抽象工廠模式,因爲他提供的產品是分屬兩個不同的等級結構。當然,如果一個工廠提供全部四種車型的產品,因爲產品分屬兩個等級結構,他當然也屬於抽象工廠模式了。
抽象工廠模式代碼:
package AbstractFactoryModel;
interface IProduct1 {
public void show();
}
interface IProduct2{
public void show();
}
class Product1 implements IProduct1{
public void show(){
System.out.println("這是1型產品");
}
}
class Product2 implements IProduct2{
public void show(){
System.out.println("這是2型產品");
}
}
interface IFactory{
public IProduct1 createProduct1();
public IProduct2 createProduct2();
}
class Factory implements IFactory{
public IProduct1 createProduct1(){
return new Product1();
}
public IProduct2 createProduct2(){
return new Product2();
}
}
客戶端代碼:
package AbstractFactoryModel;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
IFactory factory=new Factory();
factory.createProduct1().show();
factory.createProduct2().show();
}
}
四、抽象工廠模式的優缺點
優點:
(1)隔離了具體類的生成,使得客戶端並不需要知道什麼被創建。只需要改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲。
(2)當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族。
(3)增加新產品族很方便,無須修改已有系統,符合開閉原則
缺點:
增加新的產品等級結構麻煩,需要對原有系統進行較大規模的修改,甚至需要修改抽象層代碼,這顯然會帶來很大的不便,違背了開閉原則。
五、使用場景
(1)一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有類型的工廠模式都是很重要的,用戶無須關心對象的創建過程,將對象的創建和使用解耦。
(2)系統中有多於一個的產品族,但每次只使用其中某一產品族,可以通過配置文件等方式使用戶能夠動態地改變產品族,也可以很方便地增加新的產品族。
(3)屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。同一個產品族中的產品可以是沒有任何關係的對象,但是它們都具有一些共同的約束,如同一操作系統下的按鈕和文件框,按鈕和文件框之間沒有直接的關係,但它們都是屬於某一操作系統的。此時具有一個共同的約束條件:操作系統的類型。
(4)產品等級結構穩定,設計完成之後,不會向系統中增加新的產品等級結構或者刪除已有的產品等級結構。