该形式的工厂模式是我项目中用到的方法,属于很成熟的模版,读者可以直接拿来在自己项目中使用。个人感觉这种方法真正做到了“开放封闭”的原则,最大好处是用户产品类的设计完全不依赖于该模式的实现,比如提供必须的相关函数等。如果不理解工厂模式的话,请参考网上其它文章,本实现在理解上有一点小小的难度。好东西,大家慢慢享用,话不多说,先放代码!
首先是产品基类,它相当于一个接口,产品需要有什么动作就写在这里吧!
#ifndef _CPRODUCTBASE_H_ #define _CPRODUCTBASE_H_ enum PRODUCT_TYPE{PT_NOKIA=0, PT_APPLE, PT_GOOGLE}; class CProductBase{ public: CProductBase(){} ~CProductBase(){} public: virtual void doSomething()=0; }; #endif
其次,工厂类。这个类不是很好理解,首先要明白CreateByType是根据产品类型先创建了一个工厂单元,由工厂单元创建产品,map中保存的也是工厂单元。
#ifndef _DYNAMICFACTORY_H_ #define _DYNAMICFACTORY_H_ #include <map> #include "CProductBase.h" using namespace std; class CDynamicFactory{ protected: CDynamicFactory(){ m_mapType2Factor.clear(); } public: class CFactoryUnitBase{ public: virtual CProductBase* BuildProduct()=0; }; typedef std::map<PRODUCT_TYPE, CFactoryUnitBase*> MAP_TYPE_UNIT; typedef std::map<PRODUCT_TYPE, CFactoryUnitBase*>::iterator MAP_TYPE_UNIT_ITERATOR; static CDynamicFactory& GetInstance() { static CDynamicFactory nodeFactory; return nodeFactory; } CProductBase* CreateByType(PRODUCT_TYPE emType) { CFactoryUnitBase* pFactoryUnit(NULL); CProductBase* pProduct(NULL); MAP_TYPE_UNIT_ITERATOR it = m_mapType2Factor.find(emType); if (it != m_mapType2Factor.end()) { pFactoryUnit= it->second; pProduct = pFactoryUnit->BuildProduct(); } return pProduct; } void RegisterFactory(PRODUCT_TYPE emType, CFactoryUnitBase* pFactoryUnit) { m_mapType2Factor[emType] = pFactoryUnit; } private: MAP_TYPE_UNIT m_mapType2Factor; }; #endif
下面是动态创建的宏定义了,为什么能在程序运行之前map中已经有了相应类型产品的工厂,和static class_name::FactoryUnit __factory(class_name::ProductType);有很大关系,它定义了一个全局静态变量,名字可以随便取,由于初始化是在编译时进行(是吧,不是太确定?),所以就调用了FactoryUnit构造函数,然后就执行了里面的RegisterFactory。
#ifndef _PRODUCTCREATOR_H_ #define _PRODUCTCREATOR_H_ #include "DynamicFactory.h" #define DECLARE_DYNAMIC() public: static const PRODUCT_TYPE ProductType; class FactoryUnit : public CDynamicFactory::CFactoryUnitBase { public: FactoryUnit(PRODUCT_TYPE emType) { CDynamicFactory::GetInstance().RegisterFactory(emType,this); } virtual CProductBase* BuildProduct(); }; #define IMPLEMENT_DYNAMIC(class_name, emType) const PRODUCT_TYPE class_name::ProductType = emType; static class_name::FactoryUnit __factory(class_name::ProductType); CProductBase* class_name::FactoryUnit::BuildProduct() { class_name* pProduct = new class_name; return pProduct; } #endif
下面把测试程序也放上。
#ifndef _CGOOGLE_H_ #define _CGOOGLE_H_ #include "DynamicFactory.h" #include "ProductCreator.h" #include "CProductBase.h" class CGoogle : public CProductBase{ DECLARE_DYNAMIC() public: virtual void doSomething(); }; #endif
#include "CGoogle.h" #include <iostream> using std::cout; using std::endl; IMPLEMENT_DYNAMIC(CGoogle, PT_GOOGLE); void CGoogle::doSomething(){ cout<<"In Google"<<endl; }
#ifndef _CNOKIA_H_ #define _CNOKIA_H_ #include "DynamicFactory.h" #include "ProductCreator.h" #include "CProductBase.h" class CNokia: public CProductBase{ DECLARE_DYNAMIC() public: virtual void doSomething(); }; #endif
#include "CNokia.h" #include <iostream> using std::cout; using std::endl; IMPLEMENT_DYNAMIC(CNokia, PT_NOKIA); void CNokia::doSomething(){ cout<<"In Nokia"<<endl; }
main函数。
#include "DynamicFactory.h" #include "ProductCreator.h" #include "CGoogle.h" #include "CNokia.h" int main() { CNokia *p = (CNokia*)CDynamicFactory::GetInstance().CreateByType(PT_NOKIA); p->doSomething(); delete p; //注意 p = NULL; return 0; }
注意:该模式BuildProduct( )中new了产品对象,程序中使用完了一定记得delete掉.
这也是我觉得该实现唯一比较糟糕的地方,依赖于用户行为了。如果大家有什么好方法,不妨告诉我!
下面是另一网友用动态创建的方法写的工厂模式,读者可以一起参考:
http://blog.csdn.net/happyanger6/article/details/7277638
设计模式之工厂模式:模拟DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC动态创建类对象
时间: 2024-10-22 07:49:04