標籤:class blog http com 使用 檔案
一、概述
與簡單原廠模式相比,原廠模式使一個類的執行個體化延遲到了其子類處理,改善了簡單工廠對修改不能關閉的問題。
這裡我們要關注的是代碼的變化:與簡單原廠模式相比,與產品類相關的類保持不變,但與工廠類相關的類會有變化。
所以這裡有關產品的類的實現完全照搬了簡單工廠的代碼。我們只要關注工廠類的變化,就可理解原廠模式的真正意圖。
優點:
1)解決了簡單工廠的修改不能關閉的問題,系統新增產品時,新增一個產品工廠即可,工廠基類不受影響。
也就是說:當新增產品時,就由工廠類派生出一些子類,讓這些子類生產(new)其所對應的產品。當新增產品的時候,工廠類保持不變,只要增加一工廠衍生類別即可完成。
缺點:
1)無法建立多個系列的產品
2)當一個類不知道它所必須建立的對象的類的時候
3)當一個類希望由它的子類來指定它所建立的對象的時候
4)當類將建立對象的職責委託給多個協助子類中的某一個,並且你希望將哪一個協助子類是代理者這一資訊局部化的時候。
簡而言之:
原廠模式的做法相當於把簡單工廠調用產品的操作放到了原廠模式的衍生類別裡面。我們所做的就是定義一個建立所有產品的公用介面,供工廠衍生類別使用。
Product類簇保持不變,提供產品的公用屬性介面;結構上繼續保持2層結構。
Factory類簇發生改變,提供產品的公用建立介面;結構上變成2層結構:工廠類-工廠子類
二、類圖
三、代碼
IProduct.h,IProduct.cpp (見簡單原廠模式代碼)
ConcreteProductA.h,ConcreteProductA.cpp (同上)
ConcreteProductB.h, ConcreteProductB.cpp (同上)
ConcreteProductNew.h
#pragma once#include "IProduct.h"//新增產品時:增加產品衍生類別:CConcreteProductNewclass CConcreteProductNew :public IProduct{public:CConcreteProductNew();virtual ~CConcreteProductNew();public:virtual void Function();};
ConcreteProductNew.cpp
#include "ConcreteProductNew.h"CConcreteProductNew::CConcreteProductNew(){cout<<__FUNCTION__<<endl;}CConcreteProductNew::~CConcreteProductNew(){cout<<__FUNCTION__<<endl;}void CConcreteProductNew::Function(){cout<<__FUNCTION__<<endl;}
IFactory.h
#include "IProduct.h"/*簡單工廠類:是用來專門調用產品的,當有新的產品需求時,就會在工廠類內添加代碼,破壞了原廠模式的封裝性也就是說:這是一種“工廠類”對應“產品衍生類別”的方式,一旦有新的產品類,就會動到工廠類。工廠類: 提供了一個調用產品的虛介面,將自身已有的產品以派生子類的方式保護起來,若有新的產品需求則會以新的衍生類別加以實現,而不會動到原有的代碼,保證了封裝性。 也就是說:這是一種:“工廠衍生類別”對應其“產品衍生類別”的方式,當有新的產品類時,只需要從工廠基類中派生出子類加以實現就行了。*/class IFactory{public:IFactory();virtual ~IFactory();public:virtual IProduct *CreateProduct(int nType = 0) = 0;};
IFactory.cpp
#include "IFactory.h"IFactory::IFactory(){}IFactory::~IFactory(){}
ConcreteFactory1.h
#pragma once#include "IFactory.h" //工廠衍生類別:工廠基類,//下面的標頭檔是應該放在cpp檔案裡面的#include "ConcreteProductA.h"#include "ConcreteProductB.h"class ConcreteFactory1 :public IFactory{public:ConcreteFactory1();virtual ~ConcreteFactory1();public:virtual IProduct *CreateProduct(int nType = 0);};
ConcreteFactory1.cpp
#include "ConcreteFactory1.h"ConcreteFactory1::ConcreteFactory1(){}ConcreteFactory1::~ConcreteFactory1(){}IProduct *ConcreteFactory1::CreateProduct(int nType){IProduct *ptr = NULL;switch (nType){case 0:ptr = new CConcreteProductA();break;case 1:ptr = new CConcreteProductB();break;default:ptr = new CConcreteProductA();}return ptr;}
ConcreteFactoryNew.h
#pragma once#include "IFactory.h"//這個標頭檔,應該放在cpp內#include "ConcreteProductNew.h"//新增產品時,增加工廠衍生類別: ConcreteFactoryNewclass CConcreteFactoryNew :public IFactory{public:CConcreteFactoryNew();virtual ~CConcreteFactoryNew();public:virtual IProduct *CreateProduct(int nType = 0);};
ConcreteFactoryNew.cpp
#include "ConcreteFactoryNew.h"CConcreteFactoryNew::CConcreteFactoryNew(){}CConcreteFactoryNew::~CConcreteFactoryNew(){}IProduct *CConcreteFactoryNew::CreateProduct(int nType){return new CConcreteProductNew();}
main.cpp
#include "IFactory.h"#include "IProduct.h"#include "ConcreteFactory1.h"#include "ConcreteFactoryNew.h"#include <iostream>using namespace std;int main(){//可以當作是調用已有產品的工廠介面cout<<"Call inner Product:"<<endl;IFactory *pFactroy = new ConcreteFactory1();IProduct *pProduct = pFactroy->CreateProduct(0);pProduct->Function();delete pProduct;pProduct = NULL;pProduct = pFactroy->CreateProduct(1);pProduct->Function();delete pProduct;pProduct = NULL;delete pFactroy;pFactroy = NULL;//調用新產品的工廠介面cout<<"Call New Product:"<<endl;pFactroy = new CConcreteFactoryNew;pProduct = pFactroy->CreateProduct();pProduct->Function();delete pProduct;pProduct = NULL;delete pFactroy;pFactroy = NULL;return 0;}
四、運行結果
Call inner Product:
CConcreteProductA::CConcreteProductA
CConcreteProductA::Function
CConcreteProductA::~CConcreteProductA
CConcreteProductB::CConcreteProductB
CConcreteProductB::Function
CConcreteProductB::~CConcreteProductB
Call New Product:
CConcreteProductNew::CConcreteProductNew
CConcreteProductNew::Function
CConcreteProductNew::~CConcreteProductNew
請按任意鍵繼續. . .