標籤:class blog http com 使用 檔案
一、概述
###抽象原廠模式,以一個鞋業代理工廠為例(可代理生產Nike,Adidas的鞋子)
ConcreteFactory1, ConcreteFactory2 這裡對執行個體工廠的分類,每一個執行個體工廠對應一可以看做是生產同一系列(品種)下的產品,
舉例:前者代表Nike鞋工廠類,後者代表Adidas鞋工廠類。
ConcreteProductA, ConcreteProductB 這裡對執行個體產品的分類,每一個執行個體產品可以看做是不同系列的產品集合,
如:分別代表各式鞋子,分別代表布鞋(派生出nike布鞋,adidas布鞋)和皮鞋(派生出nike皮鞋,adidas皮鞋)
1,2,3......代表品種(系列):如NIKE, ADIDAS
A,B,C......代表產品,其衍生類別可延伸出各種品種(系列)下的產品,如布鞋,皮鞋
說明:
原廠模式下,對管理的產品沒有做進一步的分類,擷取所有產品的傳回值都是它們的虛基類,只能看做是對某一類類的操作。
而抽象原廠模式,則對產品進行規劃的基礎上,又再次細分成產品系列;對工廠類也做了擴充,返回不再是產品的公用虛基類,而是產品所在系列的基類。
這正如一家鞋業代理工廠要生產鞋子一樣,如果它代理10家的品牌,這10家品牌都從一個碼頭出貨,哇哢哢,出貨碼頭人來人往,貨來貨往,好像有點堵哦。
而抽象工廠將產品劃分到系列,為每個系列定義介面,這樣一來,每個品牌的鞋子都有自己的通道來接貨,各品牌之間相互獨立,碼頭也變得井然有序了。
###原廠模式
ConcreteFactory1 :生產(new)多個產品,返回產品的虛基類。
ConcreteProductA :最終產品,基於虛基類
###抽象原廠模式
ConcreteFactory1 : 生產(new)本系列的多個產品,而且同款產品會存在多個系列,
ConcreteProductA : 中間產品,上基於虛基類,下派生不同系列下的同款產品
優點:新增系列產品,只需要新增一個工廠即可。
缺點:新增某一新產品時,就變得困難了
總結:
抽象工廠不僅對產品類做了規劃,同時也對工廠類做了改善。具體表現為:對產品的規劃變成了3層結構:產品虛基類-產品系列子類-產品子類;工廠仍保持2層結構,但在第2層做了擴充:工廠虛基類-建立產品系列子類
我們前面說過,標準工廠的做法就是定義一個建立所有產品的公用介面,供工廠衍生類別使用。
當產品過多時,使用標準工廠就有些力不從心,因為這些產品都來自於同一個介面,是非常不利於管理的。
二、類圖
三、代碼
IProduct.h, IProduct.cpp (見簡單原廠模式)
ConcreteProductA.h, ConcreteProductA.cpp (同上)
ConcreteProductB.h, ConcreteProductB.cpp (同上)
ConcreteProductA1.h //產品A: 系列1下的產品A
#pragma once#include "ConcreteProductA.h"class CConcreteProductA1 :public CConcreteProductA{public:CConcreteProductA1();virtual ~CConcreteProductA1();public:virtual void Function();};
ConcreteProductA1.cpp
#include "ConcreteProductA1.h"CConcreteProductA1::CConcreteProductA1(){cout<<__FUNCTION__<<endl;}CConcreteProductA1::~CConcreteProductA1(){cout<<__FUNCTION__<<endl;}void CConcreteProductA1::Function(){cout<<__FUNCTION__<<endl;}
ConcreteProductA2.h
#pragma once#include "ConcreteProductA.h"class CConcreteProductA2 :public CConcreteProductA{public:CConcreteProductA2();virtual ~CConcreteProductA2();public:virtual void Function();};
ConcreteProductA2.cpp
#include "ConcreteProductA2.h"CConcreteProductA2::CConcreteProductA2(){cout<<__FUNCTION__<<endl;}CConcreteProductA2::~CConcreteProductA2(){cout<<__FUNCTION__<<endl;}void CConcreteProductA2::Function(){cout<<__FUNCTION__<<endl;}
ConcreteProductB1.h
#pragma once#include "ConcreteProductB.h"class CConcreteProductB1 :public CConcreteProductB{public:CConcreteProductB1();virtual ~CConcreteProductB1();public:virtual void Function();};
ConcreteProductB1.cpp
#include "ConcreteProductB1.h"CConcreteProductB1::CConcreteProductB1(){cout<<__FUNCTION__<<endl;}CConcreteProductB1::~CConcreteProductB1(){cout<<__FUNCTION__<<endl;}void CConcreteProductB1::Function(){cout<<__FUNCTION__<<endl;}
ConcreteProductB2.h
#pragma once#include "ConcreteProductB.h"class CConcreteProductB2 :public CConcreteProductB{public:CConcreteProductB2();virtual ~CConcreteProductB2();public:virtual void Function();};
ConcreteProductB2.cpp
#include "ConcreteProductB2.h"CConcreteProductB2::CConcreteProductB2(){cout<<__FUNCTION__<<endl;}CConcreteProductB2::~CConcreteProductB2(){cout<<__FUNCTION__<<endl;}void CConcreteProductB2::Function(){cout<<__FUNCTION__<<endl;}
IAbstractFactory.h
#pragma once//抽象工廠類要建立多個系列產品,所以要#include產品系列的類進來#include "ConcreteProductA.h"#include "ConcreteProductB.h"class IAbstractFactory{public:IAbstractFactory();virtual ~IAbstractFactory();public:virtual CConcreteProductA *CreateA() = 0;virtual CConcreteProductB *CreateB() = 0;};
IAbstractFactory.cpp
#include "IAbstractFactory.h"IAbstractFactory::IAbstractFactory(){}IAbstractFactory::~IAbstractFactory(){}
ConcreteAbsFactory1.h
#pragma once#include "IAbstractFactory.h" //應該放在cpp檔案裡面#include "ConcreteProductA1.h"#include "ConcreteProductB1.h"//工廠衍生類別1:建立某一系列下的產品,class CConcreteAbsFactory1 :public IAbstractFactory{public:CConcreteAbsFactory1();virtual ~CConcreteAbsFactory1();public:virtual CConcreteProductA *CreateA();virtual CConcreteProductB *CreateB();};
ConcreteAbsFactory1.cpp
#include "ConcreteAbsFactory1.h"CConcreteAbsFactory1::CConcreteAbsFactory1(){}CConcreteAbsFactory1::~CConcreteAbsFactory1(){}CConcreteProductA *CConcreteAbsFactory1::CreateA(){return new CConcreteProductA1();}CConcreteProductB *CConcreteAbsFactory1::CreateB(){return new CConcreteProductB1();}
ConcreteAbsFactory2.h
#pragma once#include "IAbstractFactory.h" //應該放在cpp檔案裡面#include "ConcreteProductA2.h"#include "ConcreteProductB2.h"//工廠衍生類別2:建立某一系列下的產品,class CConcreteAbsFactory2 :public IAbstractFactory{public:CConcreteAbsFactory2();virtual ~CConcreteAbsFactory2();public:virtual CConcreteProductA *CreateA();virtual CConcreteProductB *CreateB();};
ConcreteAbsFactory2.cpp
#include "ConcreteAbsFactory2.h"CConcreteAbsFactory2::CConcreteAbsFactory2(){}CConcreteAbsFactory2::~CConcreteAbsFactory2(){}CConcreteProductA *CConcreteAbsFactory2::CreateA(){return new CConcreteProductA2();}CConcreteProductB *CConcreteAbsFactory2::CreateB(){return new CConcreteProductB2();}
main.cpp
#include "ConcreteAbsFactory1.h"#include "ConcreteAbsFactory2.h"#include <iostream>using namespace std;int main(){cout<<"[New ConcreteAbsFactory1]:"<<endl;IAbstractFactory *absfac1 = new CConcreteAbsFactory1();cout<<"[Create Products of 1 serial]:"<<endl; absfac1->CreateA();absfac1->CreateB();cout<<"[New ConcreteAbsFactory2]:"<<endl;IAbstractFactory *absfac2 = new CConcreteAbsFactory2();cout<<"[Create Products of 2 serial]:"<<endl; absfac2->CreateA();absfac2->CreateB();return 0;}
四、運行結果
[New ConcreteAbsFactory1]:
[Create Products of 1 serial]:
CConcreteProductA::CConcreteProductA
CConcreteProductA1::CConcreteProductA1
CConcreteProductB::CConcreteProductB
CConcreteProductB1::CConcreteProductB1
[New ConcreteAbsFactory2]:
[Create Products of 2 serial]:
CConcreteProductA::CConcreteProductA
CConcreteProductA2::CConcreteProductA2
CConcreteProductB::CConcreteProductB
CConcreteProductB2::CConcreteProductB2
請按任意鍵繼續. . .