1. 程式人生 > >大白話抽象工廠模式(Abstract Factory Pattern)

大白話抽象工廠模式(Abstract Factory Pattern)

例項分析

大白話工廠方法模式(Factory Method)一文中,我們講解了日產4S店工廠規模的擴大,建立了針對不同車型的工廠,減少了工廠的工作內容,提高了效率。下面我們繼續以4S店的故事討論抽象工廠模式。
為了滿足各個階層的客戶,日產公司推出了豪華系列品牌英菲尼迪,而且為了吸引客戶購買,購車贈送行車記錄儀,購買日產汽車贈送日產行車記錄儀。購買英菲尼迪汽車贈送英菲尼迪行車記錄儀。

通過上面的描述我們引出產品族和等級結構的定義。
產品族:即來自一個家族,比如英菲尼迪汽車和英菲尼迪行車記錄儀都來自英菲尼迪家族,日產汽車和日產行車記錄儀都來自日產家族。
等級結構:可以理解為相同的產品,比如英菲尼迪汽車和日產汽車處於同一個等級結構,英菲尼迪行車記錄儀和日產行車記錄儀處於同一個等級結構。

現在假設工廠分為日產工廠和英菲尼迪工廠,且汽車和行車記錄儀都只有一種型號。日產工廠需要生產相同產品族的日產汽車和日產行車記錄儀。英菲尼迪工廠需要生產相同產品族的英菲尼迪汽車和英菲尼迪行車記錄儀。

通過對比,發現和工廠方法模式的區別為:
工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則需要面對多個產品等級結構

程式碼如下:
程式碼片段1 汽車父類

/**
 * 汽車的父類
 * @author coderzcr
 */
public abstract class Car {
    String name;
    void printCar(){
        System.out.println(name+"汽車已製造完成");
    }
}

程式碼片段2 日產汽車

/**
 * 日產汽車
 * @author coderzcr
 */
public class NissanCar extends Car {
    NissanCar(){
        this.name = "日產";
    }
}

程式碼片段3 英菲尼迪汽車

/**
 * 英菲尼迪汽車
 * @author coderzcr
 */
public class InfinitiCar extends Car {
    InfinitiCar(){
        this.name = "英菲尼迪";
    }
}

程式碼片段4 行車記錄儀父類

/**
 * 行車記錄儀父類
 * @author coderzcr
 */
public abstract class DVR {
    String name;
    void printDVR(){
        System.out.println(name+"行車記錄儀已製造完成");
    }
}

程式碼片段5 日產行車記錄儀

/**
 * 日產行車記錄儀
 * @author coderzcr
 */
public class NissanDVR extends DVR{
    NissanDVR(){
        this.name = "日產";
    }
}

程式碼片段6 英菲尼迪行車記錄儀

/**
 * 英菲尼迪行車記錄儀
 * @author coderzcr
 */
public class InfinitiDVR extends DVR {
    InfinitiDVR(){
        this.name = "英菲尼迪";
    }

}

程式碼片段7 工廠父類

/**
 * 工廠父類
 * @author coderzcr
 */
public abstract class AbstractFactory {
    abstract Car getCar();
    abstract DVR getDVR();
}

程式碼片段8 日產工廠

/**
 * 日產工廠
 * @author coderzcr
 */
public class NissanFactory extends AbstractFactory {
    @Override
    Car getCar() {
        return new NissanCar();
    }

    @Override
    DVR getDVR() {
        return new NissanDVR();
    }
}

程式碼片段9 英菲尼迪工廠

/**
 * 英菲尼迪工廠
 * @author coderzcr
 */
public class InfinitiFactory extends AbstractFactory {
    @Override
    Car getCar() {
        return new InfinitiCar();
    }

    @Override
    DVR getDVR() {
        return new InfinitiDVR();
    }
}

圖1 類圖

抽象工廠模式定義

抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於物件建立型模式。

抽象工廠模式結構

圖2抽象工廠模式類圖

抽象工廠模式包含如下角色:

  • AbstractFactory:抽象工廠
  • ConcreteFactory:具體工廠
  • AbstractProduct:抽象產品
  • Product:具體產品

抽象工廠模式分析

優點分析

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

    缺點分析

  • 在新增新的產品物件時,難以擴充套件抽象工廠來生產新種類的產品,這是因為在抽象工廠角色中規定了所有可能被建立的產品集合,要支援新種類的產品就意味著要對該介面進行擴充套件,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
  • 開閉原則的傾斜性(增加新的工廠和產品族容易,增加新的產品等級結構麻煩)。

    參考文獻

  1. 3. 抽象工廠模式(Abstract Factory) — Graphic Design Patterns
  2. 設計模式(三)抽象工廠模式 · 寫最好的設計模式專欄 · 看雲