飞道的博客

C++的抽象工厂模式

214人阅读  评论(0)

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

C++的抽象工厂模式有如下优势:

1)正如起名字,抽象工厂模式隔离具体类的生产,使客户不需要知道什么被创建。

2)当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

3)增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

而缺点是:

增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。

下面直接给一个C++实例来说明抽象工厂模式的实现


  
  1. #include <string>
  2. #include <map>
  3. #include <list>
  4. #include <stdio.h>
  5. #define USERS_PARAM(X) X;
  6. class ZBSBase
  7. {
  8. public:
  9. ZBSBase(){}
  10. virtual bool InitParam(const std::string& strParam) = 0;
  11. virtual void Excute() = 0;
  12. virtual void End() = 0;
  13. };
  14. class ZBSMessage : public ZBSBase
  15. {
  16. public:
  17. ZBSMessage():m_bInit( false){}
  18. virtual bool InitParam(const std::string& strParam)
  19. {
  20. m_bInit = true;
  21. USERS_PARAM(strParam);
  22. return true;
  23. }
  24. virtual void Disp()
  25. {
  26. printf( "ZBSMessage::Disp!\n");
  27. }
  28. virtual void End()
  29. {
  30. printf( "ZBSMessage::End!\n");
  31. }
  32. virtual void Excute()
  33. {
  34. if (!m_bInit) return;
  35. printf( "ZBSMessage::Excute!\n");
  36. Disp();
  37. End();
  38. }
  39. protected:
  40. bool m_bInit;
  41. };
  42. class ZBSEncodeMessage : public ZBSMessage
  43. {
  44. public:
  45. ZBSEncodeMessage(){}
  46. virtual void Disp()
  47. {
  48. printf( "ZBSEncodeMessage::Disp\n");
  49. }
  50. };
  51. class ZBSJsonMessage : public ZBSMessage
  52. {
  53. public:
  54. ZBSJsonMessage(){}
  55. virtual void Disp()
  56. {
  57. printf( "ZBSJsonMessage::Disp\n");
  58. }
  59. };
  60. class ZBSXMLMessage : public ZBSMessage
  61. {
  62. public:
  63. ZBSXMLMessage(){}
  64. virtual void Disp()
  65. {
  66. printf( "ZBSXMLMessage::Disp\n");
  67. }
  68. };
  69. class ZBSCreatorBase
  70. {
  71. public:
  72. ZBSCreatorBase(){}
  73. virtual ZBSMessage* Create() = 0;
  74. };
  75. template< class T>
  76. class ZBSCreator : public ZBSCreatorBase
  77. {
  78. public:
  79. ZBSCreator( const std:: string& strkey = "") :m_strKey(strkey){}
  80. ZBSMessage* Create()
  81. {
  82. return new T;
  83. }
  84. private:
  85. std:: string m_strKey;
  86. };
  87. class ZBSFactoryMgr
  88. {
  89. ZBSFactoryMgr(){}
  90. public:
  91. static ZBSFactoryMgr& Instance()
  92. {
  93. static ZBSFactoryMgr s_Instance;
  94. return s_Instance;
  95. }
  96. void AddZBSCreator(const std::string& strClassName, ZBSCreatorBase* pZBSCreator)
  97. {
  98. if (m_mapZBSCreator.find(strClassName) == m_mapZBSCreator.end())
  99. {
  100. m_mapZBSCreator.insert( make_pair(strClassName, pZBSCreator));
  101. }
  102. }
  103. ZBSMessage* CreatorZBSInstace(const std::string& strKey)
  104. {
  105. ZBSMessage* pZBSObj = NULL;
  106. std:: map< std:: string, ZBSCreatorBase*>::iterator it;
  107. it = m_mapZBSCreator.find(strKey);
  108. if (it != m_mapZBSCreator.end())
  109. {
  110. pZBSObj = it->second->Create();
  111. }
  112. return pZBSObj;
  113. }
  114. int GetMapSize()
  115. {
  116. return m_mapZBSCreator.size();
  117. }
  118. private:
  119. std:: map< std:: string, ZBSCreatorBase*> m_mapZBSCreator;
  120. };
  121. #define REGISTER_ZBSFACTORY(ClassName)\
  122. ZBSFactoryMgr::Instance().AddZBSCreator(#ClassName, new ZBSCreator<ClassName>());
  123. extern "C" ZBSMessage* CreateZBSMessage(const std::string& strKey)
  124. {
  125. return ZBSFactoryMgr::Instance().CreatorZBSInstace(strKey);
  126. }
  127. int main()
  128. {
  129. REGISTER_ZBSFACTORY(ZBSXMLMessage);
  130. REGISTER_ZBSFACTORY(ZBSJsonMessage);
  131. REGISTER_ZBSFACTORY(ZBSEncodeMessage);
  132. ZBSMessage *pm1;
  133. ZBSMessage *pm2;
  134. ZBSMessage *pm3;
  135. std:: list<ZBSMessage*> ls;
  136. std:: list<ZBSMessage*>::iterator it;
  137. pm1 = CreateZBSMessage( "ZBSXMLMessage");
  138. pm2 = CreateZBSMessage( "ZBSJsonMessage");
  139. pm3 = CreateZBSMessage( "ZBSEncodeMessage");
  140. ls.push_back(pm1);
  141. ls.push_back(pm2);
  142. ls.push_back(pm3);
  143. int nSize = ls.size();
  144. it = ls.begin();
  145. for (it; it != ls.end(); it++)
  146. {
  147. (*it)->InitParam( "");
  148. (*it)->Excute();
  149. }
  150. return 0;
  151. }

输出结果如下:


  
  1. ZBSMessage::Excute!
  2. ZBSXMLMessage::Disp
  3. ZBSMessage::End!
  4. ZBSMessage::Excute!
  5. ZBSJsonMessage::Disp
  6. ZBSMessage::End!
  7. ZBSMessage::Excute!
  8. ZBSEncodeMessage::Disp
  9. ZBSMessage::End!

首先看下,首先声明了基类ZBSBase,之后继承ZBSBase类得到ZBSMessage类,下面定义了是那个用户用到的类,即需要“工厂生产”的类,分别用于处理Encode、Json和XML文件消息的类ZBSEncodeMessage、ZBSJsonMessage和ZBSXMLMessage。

接下来声明ZBSCreator类用来创建ZBSMessage类,ZBSFactoryMgr用来实现抽象工厂,我们来看抽象工厂的具体实现代码,首先看main函数的前3行代码:


  
  1. REGISTER_ZBSFACTORY( ZBSXMLMessage) ;
  2. REGISTER_ZBSFACTORY( ZBSJsonMessage) ;
  3. REGISTER_ZBSFACTORY( ZBSEncodeMessage) ;

以REGISTER_ZBSFACTORY(ZBSXMLMessage)为例,其实际执行的代码为(注意C++中,符号#将传入的参数变为字符串,字符串化,而符号##为合并操作符,将出现在其左右的字符序列合并成一个新的标志符,注意是标志符不是字符串):

s_Instance.AddZBSCreator(“ZBSXMLMessage”, new ZBSCreator<ZBSXMLMessage>());

即m_mapZBSCreator中插入了3个对应消息类类型的ZBSCreator类实例,这里并创建消息类实例,接着执行:


  
  1. pm1 = CreateZBSMessage( "ZBSXMLMessage");
  2. pm2 = CreateZBSMessage( "ZBSJsonMessage");
  3. pm3 = CreateZBSMessage( "ZBSEncodeMessage");

此时会新建消息类的实例并返回指针,也就是通过宏定义REGISTER_ZBSFACTORY和CreateZBSMessage就可以一抽象工厂的方式创建一个具体消息类实例并返回了指针。


转载:https://blog.csdn.net/fangfanglovezhou/article/details/115839516
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场