C++对象工厂模式:ObjectFactory学习笔记

来源:互联网 发布:淘宝二手电脑怎么检测 编辑:程序博客网 时间:2024/05/01 20:07

  对象工厂,顾名思义,就是产生对象的一个“工厂”。根据传入的一个参数而产生相应的不同种类的对象。

用于批量生成同一个父类的不同子类的对象时用到。

本学习笔记基于Singleton(单件模式)基础上进行扩展。

看《C++单件模式:Singleton学习笔记》请点击链接。

http://xcoder.in/blog/2010/11/singleton-learning.xhtml

-------------------------------------------------------------------------------------------------

对于工厂模式,网上有很多不同的实现方法。我这里是一个HGE的RPG Demo中所用的,这段代码本身写的非常的好,开始好些语句没看懂,虽然就这么几句话。花了一点时间去研究了其代码,并自己重新实现了一遍,加上了通俗易懂的注释。

工厂类以模板形式实现,基于Singleton:

Code:
  1. /**-------------------------------- 
  2.  * 对象工厂模式(Object Factory) 
  3.  * 
  4.  * Code by XadillaX 
  5.  * http://www.xcoder.in 
  6.  * Created at 2010-11-17 1:33 
  7.  */  
  8. #ifndef OBJECTFACTORY_H  
  9. #define OBJECTFACTORY_H  
  10.   
  11. #pragma once  
  12. #include <map>  
  13. #include <string>  
  14. #include "../单件模式/Singleton.h"  
  15.   
  16. template<class T>  
  17. class ObjectFactory : public Singleton<ObjectFactory<T>>  
  18. {  
  19. public:  
  20.     typedef T* (*tCreator)();                               ///< 重定义对象生成函数指针  
  21.     typedef std::map<std::string, tCreator> tCreatorMap;    ///< 对象生成函数指针map  
  22.   
  23.     /** 
  24.      * @brief 注册新“生产车间” 
  25.      * 将生成对象的函数加入对象工厂 
  26.      * 
  27.      * @param *name 类名称 
  28.      * @param procedure “生产”对象的函数 
  29.      * @return 是否成功注册 
  30.      */  
  31.     bool Register(char *type, tCreator procedure);  
  32.   
  33.     /** 
  34.      * @brief 找到“生产车间” 
  35.      * 根据传入的类名返回相应的新对象的生成函数 
  36.      * 
  37.      * @param &type 类名 
  38.      * @return 相应的新对象的生成函数 
  39.      */  
  40.     T* Create(const std::string &type);  
  41.   
  42. private:  
  43.     /** “生产车间”映射 */  
  44.     tCreatorMap _map;  
  45. };  
  46.   
  47. template<class T>  
  48. bool ObjectFactory<T>::Register(char *type, tCreator procedure)  
  49. {  
  50.     string tmp(type);  
  51.     /** 将新函数加入map中 */  
  52.     _map[tmp] = procedure;  
  53.     return _map[tmp];  
  54. }  
  55.   
  56. template<class T>  
  57. T* ObjectFactory<T>::Create(const std::string &type)  
  58. {  
  59.     /** 在映射中找到相应“生产车间” */  
  60.     tCreatorMap::iterator iter = _map.find(type);  
  61.   
  62.     /** 检测“车间”是否存在 */  
  63.     if(iter != _map.end())  
  64.     {  
  65.         /** 让返回值为相应的“生产车间” */  
  66.         tCreator r = iter->second;  
  67.   
  68.         /** 返回“生产车间” */  
  69.         return r();  
  70.     }  
  71.   
  72.     return 0;  
  73. }  
  74.   
  75. #endif  

以上就是基于单件模式而实现的工厂模式了。

在样例中,我建立了一个基类Base,然后用A和B来继承它。

在一个for循环中,交替建立了A对象和B对象。这只是一个Demo,看不出有什么方便的,感觉用一个if来各自生成就好了,就像

Code:
  1. if(type == "A") p = new A();  
  2. else p = new B();  

当然,上面也是一种方法。但是,试想一下,我们将要创建的A、B、C、D、E、F、G类放到一个配置文件中,然后我们从配置文件中读取这些数据并创建相应的对象,并且这些对象的顺序是打乱的,你就要有n个if来判断了,而且扩展性不高。用一个对象工厂进行封装的话,俨然形成了一个静而有序的生产工厂,有秩序地管理着不同的对象车间,不觉得这是一件非常美妙的事情么?

好了,话不多说,直接上Demo。

Code:
  1. #include <iostream>  
  2. #include "ObjectFactory.h"  
  3. using namespace std;  
  4.   
  5. /** 基类 */  
  6. class Base;  
  7.   
  8. /** Base类及其子类的对象工厂 */  
  9. typedef ObjectFactory<Base> BaseFactory;  
  10.   
  11. class Base  
  12. {  
  13. public:  
  14.     Base(){};  
  15.     ~Base(){};  
  16. };  
  17.   
  18. class A : public Base  
  19. {  
  20. public:  
  21.     A(){ cout << "An A object created." << endl; };  
  22.     ~A(){};  
  23. };  
  24.   
  25. class B : public Base  
  26. {  
  27. public:  
  28.     B(){ cout << "A B object Created." << endl; }  
  29.     ~B();  
  30. };  
  31.   
  32. /** 对象A的“生产车间” */  
  33. Base* ACreator()  
  34. {  
  35.     return new A();  
  36. }  
  37.   
  38. /** 对象B的“生产车间” */  
  39. Base* BCreator()  
  40. {  
  41.     return new B();  
  42. }  
  43.   
  44. /** 
  45.  * @brief 主函数 
  46.  */  
  47. int main()  
  48. {  
  49.     /** 将A、B的“生产车间”注册到对象工厂中 */  
  50.     bool AFlag = BaseFactory::Instance().Register("A", ACreator);  
  51.     bool BFlag = BaseFactory::Instance().Register("B", BCreator);  
  52.   
  53.     /** 若注册失败则退出 */  
  54.     if(!AFlag || !BFlag) exit(0);  
  55.   
  56.     Base *p;  
  57.     for(int i = 0; i < 10; i++)  
  58.     {  
  59.         string type = (i % 2) ? string("A") : string("B");  
  60.   
  61.         /** p用相应“生产车间”进行生产 */  
  62.         p = BaseFactory::Instance().Create(type);  
  63.   
  64.         delete p;  
  65.     }  
  66.   
  67.     return 0;  
  68. }  

欢迎各童鞋和我一起讨论哈!接下来我就可以用这两种模式开始深入我的HGE之旅了!

原创粉丝点击