在工廠方法模式中具體工廠負責生產具體的產品,每個具體工廠對應一種具體產品,工廠方法也具備惟一性,通常狀況下,一個具體工廠中只有一個工廠方法或者一組重載的工廠方法。可是有時候咱們須要一個工廠能夠提供多個產品對象,而不是單一的產品對象。ios
爲了更清晰地理解工廠方法模式,須要先引入兩個概念:設計模式
產品等級結構 :產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。spa
產品族 :在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不一樣產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中設計
當系統所提供的工廠所需生產的具體產品並非一個簡單的對象,而是多個位於不一樣產品等級結構中屬於不一樣類型的具體產品時須要使用抽象工廠模式。code
抽象工廠模式是全部形式的工廠模式中最爲抽象和最具通常性的一種形態。對象
抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則須要面對多個產品等級結構,一個工廠等級結構能夠負責多個不一樣產品等級結構中的產品對象的建立。當一個工廠等級結構能夠建立出分屬於不一樣產品等級結構的一個產品族中的全部對象時,抽象工廠模式比工廠方法模式更爲簡單、有效率。繼承
抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象建立型模式。接口
抽象工廠建立的是一系列相關的對象,其中建立的實現其實就是採用的工廠方法模式。在工廠Factory中的每個方法,就比如是一條生產線,而生產線實際須要生產什麼樣的產品,這是由Factory1和Factory2去決定的,這樣便延遲了具體子類的實例化;同時集中化了生產線的管理,節省了資源的浪費。ip
工廠方法模式適用於產品種類結構單一的場合,爲一類產品提供建立的接口;而抽象工廠方法適用於產品種類結構多的場合,主要用於建立一組(有多個種類)相關的產品,爲它們提供建立的接口;就是當具備多個抽象角色時,抽象工廠即可以派上用場。資源
#include <iostream> using namespace std; // Product A class ProductA { public: virtual void Show() = 0; }; class ProductA1 : public ProductA { public: void Show() { cout<<"I'm ProductA1"<<endl; } }; class ProductA2 : public ProductA { public: void Show() { cout<<"I'm ProductA2"<<endl; } }; // Product B class ProductB { public: virtual void Show() = 0; }; class ProductB1 : public ProductB { public: void Show() { cout<<"I'm ProductB1"<<endl; } }; class ProductB2 : public ProductB { public: void Show() { cout<<"I'm ProductB2"<<endl; } }; // Factory class Factory { public: virtual ProductA *CreateProductA() = 0; virtual ProductB *CreateProductB() = 0; }; class Factory1 : public Factory { public: ProductA *CreateProductA() { return new ProductA1(); } ProductB *CreateProductB() { return new ProductB1(); } }; class Factory2 : public Factory { ProductA *CreateProductA() { return new ProductA2(); } ProductB *CreateProductB() { return new ProductB2(); } }; int main(int argc, char *argv[]) { Factory *factoryObj1 = new Factory1(); ProductA *productObjA1 = factoryObj1->CreateProductA(); ProductB *productObjB1 = factoryObj1->CreateProductB(); productObjA1->Show(); productObjB1->Show(); Factory *factoryObj2 = new Factory2(); ProductA *productObjA2 = factoryObj2->CreateProductA(); ProductB *productObjB2 = factoryObj2->CreateProductB(); productObjA2->Show(); productObjB2->Show(); if (factoryObj1 != NULL) { delete factoryObj1; factoryObj1 = NULL; } if (productObjA1 != NULL) { delete productObjA1; productObjA1= NULL; } if (productObjB1 != NULL) { delete productObjB1; productObjB1 = NULL; } if (factoryObj2 != NULL) { delete factoryObj2; factoryObj2 = NULL; } if (productObjA2 != NULL) { delete productObjA2; productObjA2 = NULL; } if (productObjB2 != NULL) { delete productObjB2; productObjB2 = NULL; } }
抽象工廠模式隔離了具體類的生成,使得客戶並不須要知道什麼被建立。因爲這種隔離,更換一個具體工廠就變得相對容易。全部的具體工廠都實現了抽象工廠中定義的那些公共接口,所以只需改變具體工廠的實例,就能夠在某種程度上改變整個軟件系統的行爲。另外,應用抽象工廠模式能夠實現高內聚低耦合的設計目的,所以抽象工廠模式獲得了普遍的應用。
當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一個產品族中的對象。這對一些須要根據當前環境來決定其行爲的軟件系統來講,是一種很是實用的設計模式。
增長新的具體工廠和產品族很方便,無須修改已有系統,符合「開閉原則」。
在添加新的產品對象時,難以擴展抽象工廠來生產新種類的產品,這是由於在抽象工廠角色中規定了全部可能被建立的產品集合,要支持新種類的產品就意味着要對該接口進行擴展,而這將涉及到對抽象工廠角色及其全部子類的修改,顯然會帶來較大的不便。
開閉原則的傾斜性(增長新的工廠和產品族容易,增長新的產品等級結構麻煩)。
「開閉原則」要求系統對擴展開放,對修改封閉,經過擴展達到加強其功能的目的。對於涉及到多個產品族與多個產品等級結構的系統,其功能加強包括兩方面:
增長產品族:對於增長新的產品族,工廠方法模式很好的支持了「開閉原則」,對於新增長的產品族,只須要對應增長一個新的具體工廠便可,對已有代碼無須作任何修改。
增長新的產品等級結構:對於增長新的產品等級結構,須要修改全部的工廠角色,包括抽象工廠類,在全部的工廠類中都須要增長生產新產品的方法,不能很好地支持「開閉原則」。
抽象工廠模式的這種性質稱爲「開閉原則」的傾斜性,抽象工廠模式以一種傾斜的方式支持增長新的產品,它爲新產品族的增長提供方便,但不能爲新的產品等級結構的增長提供這樣的方便。
抽象工廠模式提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象建立型模式。
抽象工廠模式包含四個角色:抽象工廠用於聲明生成抽象產品的方法;具體工廠實現了抽象工廠聲明的生成抽象產品的方法,生成一組具體產品,這些產品構成了一個產品族,每個產品都位於某個產品等級結構中;抽象產品爲每種產品聲明接口,在抽象產品中定義了產品的抽象業務方法;具體產品定義具體工廠生產的具體產品對象,實現抽象產品接口中定義的業務方法。
抽象工廠模式是全部形式的工廠模式中最爲抽象和最具通常性的一種形態。抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則須要面對多個產品等級結構。
抽象工廠模式的主要優勢是隔離了具體類的生成,使得客戶並不須要知道什麼被建立,並且每次能夠經過具體工廠類建立一個產品族中的多個對象,增長或者替換產品族比較方便,增長新的具體工廠和產品族很方便;主要缺點在於增長新的產品等級結構很複雜,須要修改抽象工廠和全部的具體工廠類,對「開閉原則」的支持呈現傾斜性。
抽象工廠模式適用狀況包括:一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節;系統中有多於一個的產品族,而每次只使用其中某一產品族;屬於同一個產品族的產品將在一塊兒使用;系統提供一個產品類的庫,全部的產品以一樣的接口出現,從而使客戶端不依賴於具體實現。