設計模式之3--抽象工廠模式

抽象工廠模式

之前我們在學習工廠模式中,如果要增加一個產品,那麼就會同時增加一個具體產品類和對應的具體工廠類,這會導致系統中的類數量成對的增加,加重系統的負擔。而對於有些場景下我們使用的是一系列的類,這個時候我們就可以考慮將一些相關的產品組成一個產品“產品族”,然後由同一個工廠來統一生產。

在工廠模式中,每一個具體工廠都是針對一個具體產品的,工廠方法具有唯一性。那麼爲了更好的理解抽象工廠模式,先介紹兩個概念:

  1. 產品等級結構。即產品的繼承結構,如一個抽象類是電視機,那麼子類就可以有海爾電視機、TCL電視機等,抽象電視機與具體電視機之前就構成了一個產品等級結構,抽象電視機是父類,而具體電視機是子類。
  2. 產品族。產品族指同一個工廠生產的,位於不同產品等級結構的一組產品。如海爾工廠生產海爾電視機、海爾電冰箱等。

產品等級結構與產品族示意圖如下圖所示:

抽象工廠模式是所有形式的工廠模式中最爲抽象與最具有一般性的一種形式。抽象工廠模式與工廠方法模式的最大區別是:工廠方法模式針對的是一個產品等級結構,而抽象工廠模式需要面對的是多個產品等級結構,一個工廠等級結構可以負責多個不同產品等級結構中的產品對象的創建。當一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更簡單效率。

抽象工廠模式定義:提供一個創建一系列相關或者相互依賴對象的接口,而無須指定它們具有的類。抽象工廠模式又稱爲Kit模式,是一種對象創建型模式。

抽象工廠模式結構如圖所示:

在上面的結構圖中,包含以下幾個角色:

  1. 抽象工廠
    abstract class AbstractFactory {
        public abstract AbstractProductA createProductA();
        public abstract AbstractProductB createProductB();
    }
  1. 具體工廠。具體工廠實現了抽象工廠,每一個具體的工廠方法都返回一個特定的產品對象,同一個工廠創建的產品構成一個產品族
class ConcreteFactory1 extends AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 extends AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

上面的代碼中每一個具體工廠都包含兩個工廠方法,分別生產產品A和B,而A1和B1、A2和B2分別構成了一個產品族。
那麼客戶端調用的時候就可以如下實現:

class Client {
    public static void main(String args[]) {
        AbstractFactory factory;
        factory = new ConcreateFactory1();
        ProductA = factory.createProductA();
        ProductB = factory.createProductB();
    }
}

在抽象工廠模式中,增加新的產品族很方便,但是增加新的產品等級結構很麻煩,因爲當增加新的產品等級結構的話,那麼就需要修改抽象工廠的接口,之後針對每個具體工廠類修改實現。抽象工廠模式這種性質稱爲“開閉原則”的傾斜性。

總結:
所有的具體工廠都實現了抽象工廠定義的那些接口,當需要改變產品族的時候,只需要修改具體工廠的實例即可,無須知道什麼產品被創建。另外使用抽象工廠模式也能夠保證客戶端始終只使用同一個產品族中的對象。

缺點: 當增加新的產品等級結構的時候,需要對原來系統中的抽象工廠,具體工廠都進行修改,違背了開閉原則。(開閉原則的傾斜性)

優點: 系統不應當關心產品類實例是如何被創建的細節,將對象的創建和使用解耦。確保同一個產品族中的產品將在一起使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章