首页 > 代码库 > 设计模式之工厂模式:模拟DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC动态创建类对象

设计模式之工厂模式:模拟DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC动态创建类对象

该形式的工厂模式是我项目中用到的方法,属于很成熟的模版,读者可以直接拿来在自己项目中使用。个人感觉这种方法真正做到了“开放封闭”的原则,最大好处是用户产品类的设计完全不依赖于该模式的实现,比如提供必须的相关函数等。如果不理解工厂模式的话,请参考网上其它文章,本实现在理解上有一点小小的难度。好东西,大家慢慢享用,话不多说,先放代码!

首先是产品基类,它相当于一个接口,产品需要有什么动作就写在这里吧!

#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