天天看點

創造型模式之抽象工廠模式1 抽象工廠模式定義2 抽象工廠模式結構3 抽象工廠模式簡單實作4 優點和缺點5 适用環境7 工廠模式之間的差別與聯系

1 抽象工廠模式定義

抽象工廠模式(Abstract Factory Pattern)隸屬于設計模式中的建立型模式,用于産品族的建構。抽象工廠是所有形态的工廠模式中最為抽象和最具一般性的一種形态。抽象工廠是指當有多個抽象角色時使用的一種工廠模式。抽象工廠模式可以向用戶端提供一個接口,使用戶端在不必指定産品的具體情況下,建立多個産品族中的産品對象。

工廠方法模式通過引入工廠等級結構,解決了簡單工廠模式中工廠類職責太重的問題,但由于工廠方法模式中的每個工廠隻生産一類産品,可能會導緻系統中存在大量的工廠類,勢必會增加系統的開銷。此時,我們可以考慮将一些相關的産品組成一個“産品族”,由同一個工廠來統一生産,這就是抽象工廠模式的基本思想。

工廠模式中的每一個形态都是針對一定問題的解決方案,工廠方法針對的是多個産品系列結構;而抽象工廠模式針對的是多個産品族結構,一個産品族内有多個産品系列。

2 抽象工廠模式結構

創造型模式之抽象工廠模式1 抽象工廠模式定義2 抽象工廠模式結構3 抽象工廠模式簡單實作4 優點和缺點5 适用環境7 工廠模式之間的差別與聯系

在抽象工廠模式中有如下角色:

  • AbstractFactory:抽象工廠,它聲明了用來建立不同産品的方法。
  • ConcreteFactory:具體工廠,實作抽象工廠中定義的建立産品的方法。
  • AbstractProduct:抽象産品,為每種産品聲明業務方法。如上圖的AbstractProductA,AbstractProductB。
  • ConcreteProduct:具體産品,定義具體工廠生産的具體産品,并實作抽象産品中定義的業務方法。

3 抽象工廠模式簡單實作

聯想和惠普生産的電腦分為了兩個産品線,一個桌上型電腦,一個是筆記本。為了解決增加産品線的問題,我們用抽象工廠模式來進行實作。

2.1 抽象産品

首先定義抽象産品類:

public abstract class Computer {
    public abstract void showName();
}
public abstract class Mouse {
    public abstract void showName();
}
           

2.2 具體産品

public class DellComputer extends Computer {

    @Override
    public void showName() {
        System.out.println("戴爾筆記本已經生産完畢");
    }
}
public class HpComputer extends Computer {
    @Override
    public void showName() {
        System.out.println("惠普桌上型電腦已經生産完畢");
    }
}

public class DellMouse extends Mouse {
    @Override
    public void showName() {
        System.out.println("戴爾滑鼠生産完畢");
    }
}
public class HpMouse extends Mouse {
    @Override
    public void showName() {
        System.out.println("惠普滑鼠生産完畢");
    }
}

           

2.3 抽象工廠

接着建立生産電腦的抽象工廠,如下所示,

public abstract class ComputerIfactory {
    public abstract Computer productComputor();
    public abstract Mouse productMouse();
}
           

定義了兩個方法,分别用來生産台式電腦和筆記本電腦。

2.4 具體工廠

定義聯想和惠普工廠:

public class DellFactory extends ComputerIfactory {
    @Override
    public Computer productComputor() {
        return new DellComputer();
    }

    @Override
    public Mouse productMouse() {
        return new DellMouse();
    }
}
public class HpFactory extends ComputerIfactory {
    @Override
    public Computer productComputor() {
        return new HpComputer();
    }

    @Override
    public Mouse productMouse() {
        return new HpMouse();
    }
}
           

聯想工廠和惠普工廠用來生産桌上型電腦和筆記本這兩個不同産品線的電腦。

2.5 用戶端調用

public class Test {
    public static void main(String[] args) {
        ComputerIfactory dellFactory = new DellFactory();
        Computer computer = dellFactory.productComputor();
        Mouse mouse = dellFactory.productMouse();
        computer.showName();
        mouse.showName();
    }
}
           

4 優點和缺點

3.1 優點

  • 抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什麼被建立。由于這種隔離,更換一個具體工廠就變得相對容易。所有的具體工廠都實作了抽象工廠中定義的那些公共接口,是以隻需改變具體工廠的執行個體,就可以在某種程度上改變整個軟體系統的行為。另外,應用抽象工廠模式可以實作高内聚低耦合的設計目的,是以抽象工廠模式得到了廣泛的應用。
  • 當一個産品族中的多個對象被設計成一起工作時,它能夠保證用戶端始終隻使用同一個産品族中的對象。這對一些需要根據目前環境來決定其行為的軟體系統來說,是一種非常實用的設計模式。
  • 增加新的具體工廠和産品族很友善,無須修改已有系統,符合“開閉原則”。

3.2 缺點

  • 在添加新的産品對象時,難以擴充抽象工廠來生産新種類的産品,這是因為在抽象工廠角色中規定了所有可能被建立的産品集合,要支援新種類的産品就意味着要對該接口進行擴充,而這将涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
  • 開閉原則的傾斜性

    (1) 增加産品族:對于增加新的産品族,抽象工廠模式很好地支援了“開閉原則”,隻需要增加具體産品并對應增加一個新的具體工廠,對已有代碼無須做任何修改。

    (2) 增加新的産品等級結構:對于增加新的産品等級結構,需要修改所有的工廠角色,包括抽象工廠類,在所有的工廠類中都需要增加生産新産品的方法,違背了“開閉原則”。

正因為抽象工廠模式存在“開閉原則”的傾斜性,它以一種傾斜的方式來滿足“開閉原則”,為增加新産品族提供友善,但不能為增加新産品結構提供這樣的友善,是以要求設計人員在設計之初就能夠全面考慮,不會在設計完成之後向系統中增加新的産品等級結構,也不會删除已有的産品等級結構,否則将會導緻系統出現較大的修改,為後續維護工作帶來諸多麻煩。

5 适用環境

在以下情況下可以考慮使用抽象工廠模式:

  • 一個系統不應當依賴于産品類執行個體如何被建立、組合和表達的細節,這對于所有類型的工廠模式都是很重要的,使用者無須關心對象的建立過程,将對象的建立和使用解耦。
  • 系統中有多于一個的産品族,而每次隻使用其中某一産品族。可以通過配置檔案等方式來使得使用者可以動态改變産品族,也可以很友善地增加新的産品族。
  • 屬于同一個産品族的産品将在一起使用,這一限制必須在系統的設計中展現出來。同一個産品族中的産品可以是沒有任何關系的對象,但是它們都具有一些共同的限制,如同一制作水果蛋糕用的水果–草莓和芒果,草莓和芒果之間沒有直接關系,但它們都是屬于水果。
  • 産品等級結構穩定,設計完成之後,不會向系統中增加新的産品等級結構或者删除已有的産品等級結構。

抽象工廠就是針對這種非常特殊的場景而誕生的。我們可以讓一個工廠負責建立多個不同類型的對象,而不是隻建立一種對象。這樣就可以有效地減少工廠類的個數。

7 工廠模式之間的差別與聯系

簡單工廠模式

簡單工廠模式,簡而言之,就是有一個專門生産某個産品的類。比如滑鼠工廠,專業生産滑鼠,給參數0,生産戴爾滑鼠,給參數1,生産惠普滑鼠。

工廠方法模式

工廠方法模式也就是滑鼠工廠是個父類,有生産滑鼠這個接口。戴爾滑鼠工廠,惠普滑鼠工廠繼承它,可以分别生産戴爾滑鼠,惠普滑鼠。生産哪種滑鼠不再由參數決定,而是建立滑鼠工廠時,由戴爾滑鼠工廠建立。後續直接調用滑鼠工廠.生産滑鼠()即可。

抽象工廠模式

抽象工廠模式也就是不僅生産滑鼠,同時生産鍵盤。 也就是PC廠商是個父類,有生産滑鼠,生産鍵盤兩個接口。 戴爾工廠,惠普工廠繼承它,可以分别生産戴爾滑鼠+戴爾鍵盤,和惠普滑鼠+惠普鍵盤。 建立工廠時,由戴爾工廠建立。 後續工廠.生産滑鼠()則生産戴爾滑鼠,工廠.生産鍵盤()則生産戴爾鍵盤。

抽象工廠模式的退化

  • 當抽象工廠模式中每一個具體工廠類隻建立一個産品對象,也就是隻存在一個産品等級結構時,抽象工廠模式退化成工廠方法模式;

    廠,惠普工廠繼承它,可以分别生産戴爾滑鼠+戴爾鍵盤,和惠普滑鼠+惠普鍵盤。 建立工廠時,由戴爾工廠建立。 後續工廠.生産滑鼠()則生産戴爾滑鼠,工廠.生産鍵盤()則生産戴爾鍵盤。

抽象工廠模式的退化

  • 當抽象工廠模式中每一個具體工廠類隻建立一個産品對象,也就是隻存在一個産品等級結構時,抽象工廠模式退化成工廠方法模式;
  • 當工廠方法模式中抽象工廠與具體工廠合并,提供一個統一的工廠來建立産品對象,并将建立對象的工廠方法設計為靜态方法時,工廠方法模式退化成簡單工廠模式。