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


    简述:

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

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

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

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

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

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

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

    例:调用不同的数据库

    代码如下:

    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 }

    输出结果:

  • 相关阅读:
    python之 网络编程、异常处理、面向对象
    python sys模块、mongodb操作、接口开发、程序分目录、压缩解压文件
    linux安装redis完整步骤
    python之:map、filter、random、datatime,写日志,发邮件,操作mysql、redis,MD5加密,写excel
    函数、模块
    python json处理、集合操作、函数定义、文件读写
    python字典、list、字符串常见处理方法、元组、文件读写
    学习笔记
    接口测试笔记
    【04】Cent OS 7 中部署JDK + Tomcat 环境
  • 原文地址:https://www.cnblogs.com/SmallAndGreat/p/13564294.html
Copyright © 2020-2023  润新知