C++对象工厂模式:ObjectFactory学习笔记
写于
更新于大纲
对象工厂,顾名思义,就是产生对象的一个“工厂”。根据传入的一个参数而产生相应的不同种类的对象。
用于批量生成同一个父类的不同子类的对象时用到。
本学习笔记基于Singleton(单件模式)基础上进行扩展。
看《C++单件模式:Singleton学习笔记》请点击链接。
对于工厂模式,网上有很多不同的实现方法。我这里是一个HGE的RPG Demo中所用的,这段代码本身写的非常的好,开始好些语句没看懂,虽然就这么几句话。花了一点时间去研究了其代码,并自己重新实现了一遍,加上了通俗易懂的注释。
工厂类以模板形式实现,基于Singleton:
#ifndef OBJECTFACTORY_H #define OBJECTFACTORY_H #pragma once #include <map> #include <string> #include "../单件模式/Singleton.h"
template<class T> class ObjectFactory : public Singleton<ObjectFactory<T>> { public: typedef T* (*tCreator)(); typedef std::map<std::string, tCreator> tCreatorMap;
bool Register(char *type, tCreator procedure);
T* Create(const std::string &type);
private: tCreatorMap _map; };
template<class T> bool ObjectFactory<T>::Register(char *type, tCreator procedure) { string tmp(type); _map[tmp] = procedure; return _map[tmp]; }
template<class T> T* ObjectFactory<T>::Create(const std::string &type) { tCreatorMap::iterator iter = _map.find(type);
if(iter != _map.end()) { tCreator r = iter->second;
return r(); }
return 0; }
#endif
|
以上就是基於单件模式而实现的工厂模式了。
在样例中,我建立了一个基类Base,然后用A和B来继承它。
在一个for循环中,交替建立了A对象和B对象。这只是一个Demo,看不出有什么方便的,感觉用一个if来各自生成就好了,就像
if(type == "A") p = new A(); else p = new B();
|
当然,上面也是一种方法。但是,试想一下,我们将要创建的A、B、C、D、E、F、G类放到一个配置文件中,然后我们从配置文件中读取这些数据并创建相应的对象,并且这些对象的顺序是打乱的,你就要有n个if来判断了,而且扩展性不高。用一个对象工厂进行封装的话,俨然形成了一个静而有序的生产工厂,有秩序地管理着不同的对象车间,不觉得这是一件非常美妙的事情么?
好了,话不多说,直接上Demo。
#include <iostream> #include "ObjectFactory.h" using namespace std;
class Base;
typedef ObjectFactory<Base> BaseFactory;
class Base { public: Base(){}; ~Base(){}; };
class A : public Base { public: A(){ cout << "An A object created." << endl; }; ~A(){}; };
class B : public Base { public: B(){ cout << "A B object Created." << endl; } ~B(); };
Base* ACreator() { return new A(); }
Base* BCreator() { return new B(); }
int main() { bool AFlag = BaseFactory::Instance().Register("A", ACreator); bool BFlag = BaseFactory::Instance().Register("B", BCreator);
if(!AFlag || !BFlag) exit(0);
Base *p; for(int i = 0; i < 10; i++) { string type = (i % 2) ? string("A") : string("B");
p = BaseFactory::Instance().Create(type);
delete p; }
return 0; }
|