设计模式之工厂模式:模拟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

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

时间: 2024-10-22 07:49:04

设计模式之工厂模式:模拟DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC动态创建类对象的相关文章

js设计模式:工厂模式、构造函数模式、原型模式、混合模式

一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.age = "27"; o1.msg = function(){ console.log("姓名:"+this.name+"  性别:"+this.sex+"  年龄:"+this.age); } var o2 = new Object(); o2.nam

浅析设计模式之八 工厂模式

工厂模式被传的太多(有点烂大街的味道)我也就不贴代码了 简单工厂模式 不是设计模式,更像是一种编程习惯 设计模式中,所谓"实现一个接口"并"不一定"表示写一个类,implements某个Java接口 "实现一个 接口"泛指"实现某个超类型(可以是接口 或者接口 某个方法)" 所有的工厂模式用来封装对象的创建 工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么 组成元素: 创建者类(cr

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

JS 设计模式(工厂模式环境搭建)

<!--引入的核心JS文件--> <script type="text/javascript" src="CommonUtil.js"></script> <script type=text/javascript charset=utf-8> <!--JS设计模式(工厂模式)--> //搭建一个工厂环境 //卖车店 function CarShop(){}; CarShop.prototype={ cons

《大话设计模式》——工厂模式的逐步升级

大话设计模式是面向对象编程的进一步的剖析,等自己学过设计模式之后,才知道面向对象编程的几大大特征-抽象.封装.继承.多态的妙用.设计模式可以说是将这几大特征玩转的淋漓尽致啊.这几天学了设计模式中的工厂模式,觉得有必要总结一下,下面我来谈谈简单工厂模式,工厂方法模式,抽象工厂模式的特点. 一.简单工厂模式 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个子类类(这些子类继承自一个父类或接口)的实例.在父类中定义了一个虚拟的方法,让子类去继承父类,然后到子类中再去重写虚拟的方法

设计模式 5 —— 工厂模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 5 -- 工厂模式,布布扣,bubuko.com

Head First 设计模式之工厂模式(Factory Pattern)

前言: 除了使用new操作符之外,还有更多制造对象的方法.你将了解到实例化这个活动不应该总是公开的进行,也会意识到初始化会造成“耦合”的问题.工厂模式将会从复杂的依赖中帮你脱困. 1.   简单的工厂 当看到“new”,就会想到“具体”,的确也是在实例化一个具体的类,而不是接口.代码绑着具体的类导致代码更脆弱,更缺乏弹性.当有一群相关的具体类时,通常会有如下代码: Duck duck: If(picnic) duck=new MallardDuck(); else if(hunting) duc

php设计模式:工厂模式

意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂模式实现: 工厂模式中任何创建对象的工厂类都要实现这个接口,实现接口的方法体中都要实现接口中的方法,它声明了工厂方法,该方法返回一个Product类型的对象. 工厂模式适用场景:1.当一个类不知道它所必须创建的对象的类的时候2.当一个类希望由它的子类来指定它所创建的对象的时候3.当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候 实例: <?php /** * 抽象工厂角色 *

浅析JAVA设计模式之工厂模式(一)

1 工厂模式简介 工厂模式的定义:简单地说,用来实例化对象,代替new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式可以动态决定将哪一个类实例化,不用先知道每次要实例化哪一个类. 工厂模式可以分一下三种形态: 简单工厂 (Simple Factory)模式:又称静态工厂模式(StaticFactory). 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory). 抽象工厂 (Abstract Factroy)模式:又称工具箱模式