1. 程式人生 > >Java 設計模式(三):抽象工廠模式

Java 設計模式(三):抽象工廠模式

參考連結:抽象工廠模式-Abstract Factory Pattern

工廠方法模式解決了簡單工廠模式存在的問題,但由於工廠方法模式中的每個工廠只生產一類產品,可能會導致系統中存在大量的工廠類,勢必會增加系統的開銷。此時,我們可以考慮將一些相關的產品組成一個“產品族”,由同一個工廠來統一生產,這就是我們本文將要學習的抽象工廠模式的基本思想。

1. 模式概述

定義:提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。

在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用於產生多種不同型別的產品,這些產品構成了一個產品族,抽象工廠模式結構如圖所示:
在這裡插入圖片描述


在抽象工廠模式中包含如下幾個角色:

  • AbstractFactory(抽象工廠):它宣告一組用於建立一族產品的方法,每一個方法對應一種產品。
  • ConcreteFactory(具體工廠):它實現抽象工廠中宣告的建立產品的方法,生成一組具體產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。
  • AbstractProduct(抽象產品):它為每種產品宣告介面,在抽象產品中聲明瞭產品所具有的業務方法。
  • ConcreteProduct(具體產品):它定義具體工廠生產的具體產品物件,實現抽象產品介面中宣告的業務方法。

在抽象工廠中宣告多個工廠方法,用於建立不同型別的產品,抽象工廠可以是介面,也可以是抽象類或者具體類,其典型程式碼如下所示:

public abstract class AbstractFactory {
    public abstract Color getColor();
    public abstract Shape getShape();
}

具體工廠實現抽象工廠,每一個具體的工廠方法可以返回一個特定的產品物件,而同一個具體工廠所建立的產品物件構成了一個產品族。對於每一個具體工廠類,其典型程式碼如下所示:

public class BlueCircleFactory extends AbstractFactory {

    @Override
    public Color getColor
() { return new Blue(); } @Override public Shape getShape() { return new Circle(); } }
public class RedRectangleFactory extends AbstractFactory {

    @Override
    public Color getColor() {
        return new Red();
    }

    @Override
    public Shape getShape() {
        return new Rectangle();
    }
}

與工廠方法模式一樣,抽象工廠模式也可為每一種產品提供一組過載的工廠方法,以不同的方式對產品物件進行建立。

抽象工廠模式同樣可以通過讀取配置檔案生成對應的產品,不再贅述。

2. “開閉原則”的傾斜性

針對概述中的例子,如果有一個新的需求,要在抽象工廠類中新增一個工廠方法getSize(),那麼我們就需要修改每個具體工廠類,實現getSize()方法,不符合“開閉原則”。

那麼怎麼辦?答案是抽象工廠模式無法解決該問題,這也是抽象工廠模式最大的缺點。在抽象工廠模式中,增加新的產品族很方便,但是增加新的產品等級結構很麻煩,抽象工廠模式的這種性質稱為“開閉原則”的傾斜性。

“開閉原則”要求系統對擴充套件開放,對修改封閉,通過擴充套件達到增強其功能的目的,對於涉及到多個產品族與多個產品等級結構的系統,其功能增強包括兩方面:

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

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

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

3. 模式總結

抽象工廠模式是工廠方法模式的進一步延伸,由於它提供了功能更為強大的工廠類並且具備較好的可擴充套件性,在軟體開發中得以廣泛應用,尤其是在一些框架和API類庫的設計中,例如在Java語言的AWT(抽象視窗工具包)中就使用了抽象工廠模式,它使用抽象工廠模式來實現在不同的作業系統中應用程式呈現與所在作業系統一致的外觀介面。抽象工廠模式也是在軟體開發中最常用的設計模式之一。

  1. 主要優點
    ① 抽象工廠模式隔離了具體類的生成,由於這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現了抽象工廠中定義的那些公共介面,因此只需改變具體工廠的例項,就可以在某種程度上改變整個軟體系統的行為。
    ② 當一個產品族中的多個物件被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的物件。
    ③ 增加新的產品族很方便,無須修改已有系統,符合“開閉原則”。

  2. 主要缺點
    ① 增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層程式碼,違背了“開閉原則”。

  3. 適用場景
    ① 使用者不關心物件的建立過程,將物件的建立和使用解耦。
    ② 系統中有多於一個的產品族,而每次只使用其中某一產品族。
    ③ 產品等級結構穩定,不會向系統中增加新的產品等級結構或者刪除已有的產品等級結構。

4. 思考

抽象工廠模式是否符合“開閉原則”?【從增加新的產品等級結構和增加新的產品族兩方面進行思考。】

答案已經給出。