工厂模式用来封装具体对象的创建,但我们没写一个具体的需要创建的对象类,是否要修改工厂呢?或者需要在某个地方进行注册。这样,每写一个具体的对象类,还需要在另外一个地方编写注册代码,程序员都是懒人,能省事儿,绝不费事儿。看代码:
#pragma once
#include "T_KeyPVector.h"
using namespace std;
/**
*ICreator 是创建器接口,它创建RootClass类型的对象,具体类型可以是RootClass类的子类
*/
template<class RootClass>
class ICreator
{
public:
virtual RootClass* Create() = 0;
};
/**
*Creator 是ICreator的实现
*ConcreateClass是RootClass的子类,Creator创建ConcreateClass,
*以RootClass的形式返回创建的对象
*/
template<class ConcreteClass,class RootClass>
class Creator : public ICreator<RootClass>
{
public:
virtual RootClass* Create()
{
return new ConcreteClass();
}
};
/**
*工厂负责具体创建对象,工厂注册了各种RootClass子类的创建器
*并使用这些创建器根据Key值来创建具体对象。
*工厂是用户主要使用的类,此工厂具体使用的时候需要具体实现为一个Singleton的
*具体的Singleton的工厂加以应用
*/
template <class RootClass,class KeyType>
class Factory
{
public:
typedef ICreator<RootClass> CCreator;
typedef T_KeyVector<KeyType,CCreator*> CreatorMap;
public:
class Iterator
{
public:
Iterator(CreatorMap* pMap)
:m_pMap(pMap),m_it(pMap->begin())
{
}
Iterator(CreatorMap* pMap,int index)
:m_it(pMap->get(index))
{
}
Iterator(const Iterator& it)
:m_pMap(it.m_pMap)
,m_it(it.m_it){}
Iterator& operator = (const Iterator& it)
{
if(this == &it)
return *this;
m_pMap = it.m_pMap;
m_it = it.m_it;
return *this;
}
~Iterator(){}
public:
bool valid()
{
return m_it.valid();
}
void next()
{
m_it.next();
}
RootClass* Create()
{
return (*m_it)->Create();
}
KeyType key()
{
return m_it.key();
}
private:
CreatorMap* m_pMap;
typename CreatorMap::Iterator m_it;
};
private:
typedef pair<KeyType,CCreator*> MapPair;
public:
RootClass* Create(KeyType key)
{
CreatorMap::Iterator it = m_mapCreators.find(key);
if(it.valid())
{
return (*it)->Create();
}
return NULL;
}
void Registe(KeyType key,CCreator* pCreator)
{
m_mapCreators.push_back(key,pCreator);
}
void Deregiste(KeyType key)
{
m_mapCreators.erase(key);
}
Iterator begin()
{
return Iterator(&m_mapCreators);
}
virtual ~Factory()
{
m_mapCreators.clear();
};
int size()
{
return (int)m_mapCreators.size();
}
Iterator get(int index)
{
return Iterator(&m_mapCreators,index);
}
protected:
Factory(){};
private:
CreatorMap m_mapCreators;
};
/**
*注册代理器,用户使用这个类在Factory中注册Creator,注册过程为在.cpp中声明静态注册代理类变量即可
*ConcreateClass:Factory中要生成的类
*RootClass:Factory中执行生成动作后返回的类型(RootClass是ConcreateClass的父类)
*KeyType:使用那种类型来标识生要生成的对象类型。
*SingletonFactory:Factory的子类,要求其是一个单间模式的类,是真正的工厂
*/
template<class ConcreteClass,class RootClass,class KeyType,class SingletonFactory>
class RegisteProxy
{
public:
typedef Creator<ConcreteClass,RootClass> CCreator;
public:
RegisteProxy(KeyType key)
{
m_key = key;
SingletonFactory::Instance().Registe(key,&m_creator);
}
~RegisteProxy()
{
SingletonFactory::Instance().Deregiste(m_key);
}
private:
CCreator m_creator;
KeyType m_key;
};
/**
*使用宏来简化注册过程,用户在编写一个IClassname的具体实现类的时候,可以在其.cpp最后使用这个宏来注册
*/
#define REGISTE_CREATOR(SingletonFactory, ConcreateClassname,IClassname,KeyTypename,key) \
static RegisteProxy<ConcreateClassname,IClassname,KeyTypename,SingletonFactory> \
g_proxy_##ConcreateClassname(key);
/**
*声明单件的Factory,并将此类作为导出类
*当用户在Dll中使用工厂的时候,一般使用此宏来声明SingletonFactory
*/
#define DECLEAR_SINGLETON_FACTORY_EXT(SingletonFactory, IClassname, KeyTypename) \
class AFX_EXT_CLASS SingletonFactory : public Factory<IClassname,KeyTypename> \
{ \
protected: \
SingletonFactory(){}; \
public: \
static SingletonFactory& Instance(); \
};
/**
*声明单件Factory
*/
#define DECLEAR_SINGLETON_FACTORY(SingletonFactory, IClassname, KeyTypename) \
class SingletonFactory : public Factory<IClassname,KeyTypename> \
{ \
protected: \
SingletonFactory(){}; \
public: \
static SingletonFactory& Instance(); \
};
/**
*单件的Factory的实现代码
*/
#define IMPLEMENT_SINGLETON_FACTORY(SingletonFactory) \
SingletonFactory& SingletonFactory::Instance() \
{ \
static SingletonFactory f; \
return f; \
}
注册代理和几个宏,可以让我们大大减少工厂应用的代价,而且,这段工厂代码是通用代码,只要几行配置,就能得到一个工厂,并且可以方便的注册。下面是应用实例:
class IObj
{
public:
virtual ~IObj();
}
下面我要创建一个创建以IObj为基类的对象的工厂:
#pragma once
#include "Factory.h"
class IGEObj;
DECLEAR_SINGLETON_FACTORY(Obj_Factory,IObj,CString)
#define REGISTE_OBJ(classname) \
REGISTE_CREATOR(Obj_Factory,classname,IObj,CString,#classname)
#define Create_Obj(classname)\
dynamic_cast<classname*>(Obj_Factory::Instance().Create(#classname))
#define Create_Obj_2(key) \
Obj_Factory::Instance().Create(key)
以上是头文件代码,下面是cpp文件代码:只有一行
IMPLEMENT_SINGLETON_FACTORY(GEObj_Factory)
这样工厂就定义好了:工厂名称为Obj_Factory。可以使用宏REGISTE_OBJ(classname)注册一个具体需要创建的IObj的子类,然后根据注册宏的参数来创建对象。关键是这个宏可以直接写在具体类的cpp文件末尾。例:
/*头文件代码*/
class Text_Obj : public IObj
{
public:
Text_Obj ();
~ Text_Obj();
};
/*cpp文件代码*/
Text_Obj:: Text_Obj ()
{
}
Text_Obj::~ Text_Obj()
{
}
REGISTE_OBJ(Text_Obj)//我喜欢用类名称做码,不会乱,还保证不重复
//cpp结束
然后在应用的地方:
IObj* pObj = Create_GEObj_2(”Text_Obj”);
虽然工厂写起来麻烦一些,但是使用起来却方便。比如,我们写好了抽象对象的序列化,但是读取的时候如何恢复创建对象就可以用此法,只要序列化的时候每个对象都保存一个它的码就行了。关键是,如果我们扩展另外一个对象Circle_Obj,我们只需要注册,不用更改序列化代码。如果Circle_Obj对象在上层库实现,序列化代码在底层库,就更需要了。
另外,代码中T_KeyVector是一个map的封装,理解就好。