03 抽象工廠模式

產品族與等級結構

產品等級結構:產品等級結構即產品的繼承結構。

產品族:產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品。

結構

  1. AbstractFactory(抽象工廠):他申明瞭一組用於創建一族產品的方法,每一個方法對應一種產品。
  2. ConcreteFactory(具體工廠):它實現了在抽象工廠中申明的創建產品的方法,生成一組具體產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。
  3. AbstractProduct(抽象產品):它爲每種產品申明接口,在抽象產品中聲明瞭產品所具有的業務方法。
  4. ConcretePorduct(具體產品):它定義具體工廠生產的具體產品對象,實現抽象產品中聲明的業務方法。

代碼

抽象產品A

public interface ProduceA {

    void method();

}

抽象產品B

public interface ProduceB {

    void method();

}

具體產品A1

public class ConcreteProduceA1 implements ProduceA {

    @Override
    public void method() {
        System.out.println("ConcreteProduceA1");
    }

}

具體產品A2

public class ConcreteProduceA2 implements ProduceA {

    @Override
    public void method() {
        System.out.println("ConcreteProduceA2");
    }

}

具體產品B1

public class ConcreteProduceB1 implements ProduceB {

    @Override
    public void method() {
        System.out.println("ConcreteProduceB1");
    }

}

具體產品B2

public class ConcreteProduceB2 implements ProduceB {

    @Override
    public void method() {
        System.out.println("ConcreteProduceB2");
    }

}

抽象工廠

public interface AbstractFactory {

    ProduceA createProduceA();

    ProduceB createProduceB();

}

具體工廠1

public class ConcreteFactory1 implements AbstractFactory {

    @Override
    public ProduceA createProduceA() {
        return new ConcreteProduceA1();
    }

    @Override
    public ProduceB createProduceB() {
        return new ConcreteProduceB1();
    }

}

具體工廠2

public class ConcreteFactory2 implements AbstractFactory {

    @Override
    public ProduceA createProduceA() {
        return new ConcreteProduceA2();
    }

    @Override
    public ProduceB createProduceB() {
        return new ConcreteProduceB2();
    }

}

客戶端調用

public class Client {

    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        factory1.createProduceA().method();
        factory1.createProduceB().method();

        AbstractFactory factory2 = new ConcreteFactory2();
        factory2.createProduceA().method();
        factory2.createProduceB().method();
    }

}

擴展(等級結構)

具體產品A3

public class ConcreteProduceA3 implements ProduceA {

    @Override
    public void method() {
        System.out.println("ConcreteProduceA3");
    }

}

具體產品B3

public class ConcreteProduceB3 implements ProduceB {

    @Override
    public void method() {
        System.out.println("ConcreteProduceB3");
    }

}

具體工廠3

public class ConcreteFactory3 implements AbstractFactory {

    @Override
    public ProduceA createProduceA() {
        return new ConcreteProduceA3();
    }

    @Override
    public ProduceB createProduceB() {
        return new ConcreteProduceB3();
    }

}

客戶端調用

AbstractFactory factory3 = new ConcreteFactory2();
factory3.createProduceA().method();
factory3.createProduceB().method();

開閉原則的傾斜性

如果需要新增一個產品族,需要在抽象工廠裏面新增創建該產品的方法,對應的每個具體工廠中都需要實現該方法,新建具體工廠類並實現抽象工廠中的方法。因此,在抽象工廠模式中增加新的產品族很方便,但是增減新的產品等級結構很麻煩,抽象共產模式的這種性質被稱爲開閉原則的傾斜性。開閉原則要求系統對擴展開放,對修改關閉,通過擴展達到增強某功能的目的,對於設計多個產品族與多個產品等級結構的系統,題功能增強包括兩個反方面。

  1. 增加產品族:對於增加新的產品族,抽象工廠模式很好的支持了開閉原則,只需要增加具體的產品並增加一個具體工廠,對已有的代碼無需做任何事情。
  2. 增加新的產品的等級結構:對於增加新的產品等級結構,需要修改所有的工廠角色。包括抽象工廠,在所有的工廠類中都需要增加新產品的方法,違背了開閉原則。

優/缺點與適用環境

  • 優點
  1. 抽象工廠模式隔離的具體類的生成,使客戶端並不需要知道什麼被創建。由於這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現了抽象工廠中定義的公共接口,因此只需要修改具體工廠的實例就可以在某種程度上改變軟件系統的行爲。
  2. 當一個產品族中的多個對象設計成一起工作時,他能保證客戶端只使用同一個產品族中的對象。
  3. 增加新的產品族很方便,無需修改已有的系統,符合開閉原則。
  • 缺點
  1. 增加新的產品等級結構麻煩,需要對原有的系統進行較大的修改,甚至需要修改抽象層的代碼,這顯然會帶來較大的不便,違背了開閉原則。
  • 適用環境
  1. 一個系統不應當依賴於產品類實例如何創建、組合和表達的細節,這對於所有類型的工廠模式都是很重要的,用戶無需關心對象的創建過程,將對象的創建和使用解耦。
  2. 系統中有多餘一個產品族,而每次只使用其中某一個產品族。可通過配置文件等方式是用戶能夠動態改變產品族,也可很方便的增加新的產品族。
  3. 屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。同一個產品族中的產品可以是沒有任何關閉的對象,但是他們都有一些共同的約束,如同一組操作系統下的按鈕和文本框,按鈕和文本框沒有任何直接關係,但是它們都是屬於某一操作系統的,此時具有一個共同的約束條件,即操作類型的系統。
  4. 產品等級結構穩定,在設計完成之後不會向系統中增加新的產品登等級結構或者刪除已有的等級結構。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章