011 --- 第15章 抽象工厂模式

简述:

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

  抽象工厂模式包括:抽象工厂类、具体工厂类、抽象产品类、具体产品类

    抽象工厂类,它里面应该包含所有的产品创建的抽象方法。

    具体工厂类:创建具有特定实现的产品对象。

    抽象产品类:它们都有可能有几种不同的实现。

    具体产品类:对抽象产品的具体分类的实现。

应用场景:所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,接触分支判断带来的耦合

 

注:抽象工厂模式C#可以用反射的技术来实现,但是C++没有这种已经封装好的技术,所以我自己利用MFC的动态创建对象技术来模拟了反射技术实现的抽象工厂模式。

 

注:开发环境调整为VS2017,操作系统win11

例:调用不同的数据库

代码如下:

CDynamicCreateObject.h(动态创建对象头文件):

 1 #pragma once
 2 
 3 #ifndef _DYNAMICCREATEOBJECT_H_
 4 #define _DYNAMICCREATEOBJECT_H_
 5 
 6 #include <iostream>
 7 using namespace std;
 8 
 9 #define DECLARE_DYNAMICCREATEOBJECT() \
10     static CRunTime RunTime; \
11     static CDynamicCreateObject* CreateObject();
12 
13 #define IMPLEMENT_DYNAMICCREATEOBJECT(ThisClass) \
14     CDynamicCreateObject* ThisClass::CreateObject() \
15     { \
16             return new ThisClass; \
17     } \
18     CRunTime ThisClass::RunTime = { #ThisClass, &ThisClass::CreateObject, NULL }; \
19     CInitObjectList InitObjectList##ThisClass(&ThisClass::RunTime);
20     
21 
22 class CDynamicCreateObject
23 {
24 public:
25     static CDynamicCreateObject* MateStringThenCreateObject(string szClassName);
26 };
27 
28 class CRunTime
29 {
30 public:
31     string m_szClassName;
32     CDynamicCreateObject* (*pFunCreateObject)();
33     CRunTime* pNext;
34     static CRunTime* pTop;
35 };
36 
37 class CInitObjectList
38 {
39 public:
40     CInitObjectList(CRunTime* pRunTime)
41     {
42         pRunTime->pNext = CRunTime::pTop;
43         CRunTime::pTop = pRunTime;
44     }
45 };
46 
47 #endif   //_DYNAMICCREATEOBJECT_H_

 

CDynamicCreateObject.cpp(动态创建对象源文件):

 1 #include "CDynamicCreateObject.h"
 2 
 3 CRunTime* CRunTime::pTop = NULL;
 4 
 5 CDynamicCreateObject* CDynamicCreateObject::MateStringThenCreateObject(string szClassName)
 6 {
 7     CRunTime* pRunTime = CRunTime::pTop;
 8     while (pRunTime)
 9     {
10         if (pRunTime->m_szClassName ==  szClassName)
11         {
12             if (pRunTime->pFunCreateObject == NULL)
13                 return NULL;
14             else
15                 return (*(pRunTime->pFunCreateObject))();
16         }
17         pRunTime = pRunTime->pNext;
18     }
19     return NULL;
20 }

 

抽象工厂模式代码:

  1 #include <iostream>
  2 #include <string>
  3 // 增加动态创建对象功能,这是由于C++没有C#中的反射技术,但可以自己模拟MFC中的动态创建对象技术实现
  4 #include "CDynamicCreateObject.h"
  5 using namespace std;
  6 
  7 // 用户表类
  8 class CUser
  9 {
 10 private:
 11     int m_nID;
 12     string m_szName;
 13 
 14 public:
 15     CUser() : m_nID(0), m_szName("") {};
 16 
 17     int GetID() { return m_nID; }
 18     void SetID(int nID) { m_nID = nID; }
 19 
 20     string GetName(){ return m_szName; }
 21     void SetName(string szName){ m_szName = szName; }
 22 };
 23 
 24 // 部门表类
 25 class CDepartment{};
 26 
 27 // IUser(抽象产品类)
 28 class CDatabaseUser :
 29     public CDynamicCreateObject
 30 {
 31 public:
 32     virtual void Insert(CUser* pUser) = 0;
 33     virtual CUser* GetUser(int nID) = 0;
 34 };
 35 
 36 // SQLServerUser(具体产品类)
 37 class CSQLServerUser : public CDatabaseUser
 38 {
 39 // 抽象工厂模式动态创建
 40 public:
 41     DECLARE_DYNAMICCREATEOBJECT()
 42 // 抽象工厂模式动态创建
 43 public:
 44     void Insert(CUser* pUser)
 45     {
 46         cout << "在SQL Server中给User表增加一条记录。" << endl;
 47     }
 48 
 49     CUser* GetUser(int nID)
 50     {
 51         cout << "在SQL Server中根据ID得到User表一条记录。" << endl;
 52         return NULL;
 53     }
 54 };
 55 // 抽象工厂模式动态创建
 56 IMPLEMENT_DYNAMICCREATEOBJECT(CSQLServerUser)
 57 // 抽象工厂模式动态创建
 58 
 59 // AccessUser(具体产品类)
 60 class CAccessUser : public CDatabaseUser
 61 {
 62 // 抽象工厂模式动态创建
 63 public:
 64     DECLARE_DYNAMICCREATEOBJECT()
 65 // 抽象工厂模式动态创建
 66 public:
 67     void Insert(CUser* pUser)
 68     {
 69         cout << "在Access中给User表增加一条记录。" << endl;
 70     }
 71 
 72     CUser* GetUser(int nID)
 73     {
 74         cout << "在Access中根据ID得到User表一条记录。" << endl;
 75         return NULL;
 76     }
 77 };
 78 // 抽象工厂模式动态创建
 79 IMPLEMENT_DYNAMICCREATEOBJECT(CAccessUser)
 80 // 抽象工厂模式动态创建
 81 
 82 // IDepartment(抽象产品类)
 83 class CDatabaseDepartment :
 84     public CDynamicCreateObject
 85 {
 86 public:
 87     virtual void Insert(CDepartment* pDepartment) = 0;
 88     virtual CDepartment* GetDepartment(int nID) = 0;
 89 };
 90 
 91 // SQLServerDepartment(具体产品类)
 92 class CSQLServerDepartment : public CDatabaseDepartment
 93 {
 94 // 抽象工厂模式动态创建
 95 public:
 96     DECLARE_DYNAMICCREATEOBJECT()
 97 // 抽象工厂模式动态创建
 98 public:
 99     void Insert(CDepartment* pDepartment)
100     {
101         cout << "在SQL Server中给Department表增加一条记录。" << endl;
102     }
103 
104     CDepartment* GetDepartment(int nID)
105     {
106         cout << "在SQL Server中根据ID得到Department表一条记录。" << endl;
107         return NULL;
108     }
109 };
110 // 抽象工厂模式动态创建
111 IMPLEMENT_DYNAMICCREATEOBJECT(CSQLServerDepartment)
112 // 抽象工厂模式动态创建
113 
114 // AccessDepartment(具体产品类)
115 class CAccessDepartment : public CDatabaseDepartment
116 {
117 // 抽象工厂模式动态创建
118 public:
119     DECLARE_DYNAMICCREATEOBJECT()
120 // 抽象工厂模式动态创建
121 public:
122     void Insert(CDepartment* pDepartment)
123     {
124         cout << "在Access中给Department表增加一条记录。" << endl;
125     }
126 
127     CDepartment* GetDepartment(int nID)
128     {
129         cout << "在Access中根据ID得到Department表一条记录。" << endl;
130         return NULL;
131     }
132 };
133 // 抽象工厂模式动态创建
134 IMPLEMENT_DYNAMICCREATEOBJECT(CAccessDepartment)
135 // 抽象工厂模式动态创建
136 
137 //// 工厂方法模式举例--------------------
138 //// IFactory(抽象工厂类)
139 //class CFactory
140 //{
141 //public:
142 //    virtual CDatabaseUser* CreateDatabaseUser() = 0;
143 //    virtual CDatabaseDepartment* CreateDatabaseDepartment() = 0;
144 //};
145 //
146 //// SQLServerFactory(具体工厂类)
147 //class CSQLServerFactory : public CFactory
148 //{
149 //public:
150 //    virtual CDatabaseUser* CreateDatabaseUser()
151 //    {
152 //        return new CSQLServerUser();
153 //    }
154 //
155 //    virtual CDatabaseDepartment* CreateDatabaseDepartment()
156 //    {
157 //        return new CSQLServerDepartment();
158 //    }
159 //};
160 //
161 //// AccessFactory(具体工厂类)
162 //class CAccessFactory : public CFactory
163 //{
164 //public:
165 //    virtual CDatabaseUser* CreateDatabaseUser()
166 //    {
167 //        return new CAccessUser();
168 //    }
169 //
170 //    virtual CDatabaseDepartment* CreateDatabaseDepartment()
171 //    {
172 //        return new CAccessDepartment();
173 //    }
174 //};
175 //// 工厂方法模式举例--------------------
176 //
177 //// 简单工厂模式举例--------------------
178 //// DataAccess(简单工厂模式工厂类)
179 //class CDataAccess
180 //{
181 //private:
182 //    enum DATABASE{SQLServer, Access} ;
183 //    static const int m_nDB;
184 //
185 //public:
186 //    static CDatabaseUser* CreateDatabaseUser()
187 //    {
188 //        CDatabaseUser* pDatabaseUser = NULL;
189 //        switch (m_nDB)
190 //        {
191 //        case SQLServer:
192 //            pDatabaseUser = new CSQLServerUser();
193 //            break;
194 //
195 //        case Access:
196 //            pDatabaseUser = new CAccessUser();
197 //            break;
198 //        }
199 //        
200 //        return pDatabaseUser;
201 //    }
202 //
203 //    static CDatabaseDepartment* CreateDatabaseDepartment()
204 //    {
205 //        CDatabaseDepartment* pDatabaseDepartment = NULL;
206 //        switch (m_nDB)
207 //        {
208 //        case SQLServer:
209 //            pDatabaseDepartment = new CSQLServerDepartment();
210 //            break;
211 //
212 //        case Access:
213 //            pDatabaseDepartment = new CAccessDepartment();
214 //            break;
215 //        }
216 //
217 //        return pDatabaseDepartment;
218 //    }
219 //};
220 //
221 //const int CDataAccess::m_nDB = SQLServer;
222 //// 简单工厂模式举例--------------------
223 
224 // 抽象工厂模式举例--------------------
225 // DataAccess(抽象工厂模式工厂类)
226 class CDataAccessAbstract
227 {
228 private:
229     static string m_szUserName;
230     static string m_szDepartmentName;
231 public:
232     static CDatabaseUser* CreateDatabaseUser()
233     {
234         return (CDatabaseUser*)CDynamicCreateObject::MateStringThenCreateObject(m_szUserName);
235     }
236     
237     static CDatabaseDepartment* CreateDatabaseDepartment()
238     {
239         return (CDatabaseDepartment*)CDynamicCreateObject::MateStringThenCreateObject(m_szDepartmentName);
240     }
241 };
242 // 字符串从配置文件中读取功能略(并不难,不过不需要解析xml,直接读取整行,解析键值对就可以,键值对类似于:UserName = CAccessUser)
243 string CDataAccessAbstract::m_szUserName = "CAccessUser";
244 string CDataAccessAbstract::m_szDepartmentName = "CSQLServerDepartment";
245 // 抽象工厂模式举例--------------------
246 
247 
248 int main()
249 {
250     CUser User;
251     CDepartment Department;
252 
253     CDatabaseUser* pDatabaseUser = CDataAccessAbstract::CreateDatabaseUser();
254     pDatabaseUser->Insert(&User);
255     pDatabaseUser->GetUser(1);
256     delete pDatabaseUser;
257 
258     CDatabaseDepartment* pDatabaseDepartment = CDataAccessAbstract::CreateDatabaseDepartment();
259     pDatabaseDepartment->Insert(&Department);
260     pDatabaseDepartment->GetDepartment(1);
261     delete pDatabaseDepartment;
262 
263     system("pause");
264     return 0;
265 }

 

输出结果:

 

posted @ 2020-08-26 11:56  二是一种不三不亖的范  阅读(114)  评论(0编辑  收藏  举报