设计模式的 C++ 实现---抽象工厂模式(二)

前文回顾
单例模式(一)
单例模式(二)
观察者模式
简单工厂模式
工厂方法模式(一)
工厂方法模式(二)
抽象工厂模式(一)

前言

在抽象工厂模式中,需要增加一个产品类时,需要同时增加好几个类,并且系列工厂类和客户端都得修改。可以使用简单工厂模式对抽象工厂进行改进。

实现举例

  1. 场景描述
    假设一个简单的数据管理系统:有两个 Student (学生表)和 Grades(分数)两个对象表,一般对于一个对象表需要提供了对数据库操作(增、删、改、查)的类,然而在使用过程中数据库是可能进行更换的,比如 Access 切换到 Oracel。
  2. 产品类
    ①.Student 类
class Student
{
public:
    Student(){}
};

②.Grades类

class Grades
{
public:
    Grades(){}
};

  1. 数据库操作抽象基类
    ①.StudentHelper 类
#include "student.h"

class StudentHelper
{
public:
    StudentHelper(){};
    virtual void saveStudent(const Student &) = 0;
    virtual Student getStudent(int id)= 0;
    virtual ~StudentHelper() {}
};

②.GradesHelper 类

#include "grades.h"

class GradesHelper
{
public:
    GradesHelper(){}
    virtual void saveGrades(const Grades &) = 0;
    virtual Grades getGrades(int id) = 0;
    virtual ~GradesHelper(){}
};
  1. 数据库操作派生类
    ①.StudentHelperAccess 类
#include <iostream>
#include "studenthelper.h"
using namespace std;
class StudentHelperAccess : public StudentHelper
{
public:
    StudentHelperAccess(){}
    void saveStudent(const Student &) override
    {
        cout << "使用 Access 数据库保存一个 Student 对象"<<endl;
    }
    Student getStudent(int id) override
    {
        cout << "从 Access 数据库查询一个 Student 对象"<<endl;
    }
    static void * getStudentHelperAccess(){
        return  new  StudentHelperAccess() ;
    }
};

②.StudentHelperOracel 类

#include <iostream>
#include "studenthelper.h"
using namespace std;

class StudentHelperOracel : public StudentHelper
{
public:
    StudentHelperOracel(){}
    void saveStudent(const Student &) override
    {
        cout << "使用 Oracel 数据库保存一个 Student 对象"<<endl;
    }
    Student getStudent(int id) override
    {
        cout << "从 Oracel 数据库查询一个 Student 对象"<<endl;
    }
    static void* getStudentHelperOracel(){
        return new  StudentHelperOracel() ;
    }
};

③.GradesHelperAccess 类

#include <iostream>
#include "gradeshelper.h"
using namespace std;
class GradesHelperAccess : public GradesHelper
{
public:
    GradesHelperAccess(){}
    void saveGrades(const Grades &) override
    {
        cout << "使用 Access 数据库保存一个 Grades 对象"<<endl;
    }
    Grades getGrades(int id) override
    {
        cout << "从 Access 数据库查询一个 Grades 对象"<<endl;
    }
    static void * getGradesHelperAccess(){
        return  new  GradesHelperAccess() ;
    }
};

④.GradesHelperOracel 类

#include <iostream>
#include "gradeshelper.h"
using namespace std;

class GradesHelperOracel : public GradesHelper
{
public:
    GradesHelperOracel(){}
    void saveGrades(const Grades &) override
    {
        cout << "使用 Oracel 数据库保存一个 Grades 对象"<<endl;
    }
    Grades getGrades(int id) override
    {
        cout << "从 Oracel 数据库查询一个 Grades 对象"<<endl;
    }
    static void * getGradesHelperOracel(){
        return new  GradesHelperOracel();
    }
};

  1. 工厂类
#include "studenthelperaccess.h"
#include "studenthelperoracel.h"
#include "gradeshelperaccess.h"
#include "gradeshelperoracel.h"
#include <functional>
#include <map>
using namespace std;

class DataBaseHelper
{
public:
    enum DBType{Access,Oracel};
    enum DataType{StudentTable,GradesTable};
    typedef function<void*()> Func;
public:
    DataBaseHelper()
    {
        //产品注册
        TableRegistry.insert(make_pair(make_pair(Access,StudentTable),StudentHelperAccess::getStudentHelperAccess));
        TableRegistry.insert(make_pair(make_pair(Access,GradesTable),GradesHelperAccess::getGradesHelperAccess));
        TableRegistry.insert(make_pair(make_pair(Oracel,StudentTable),StudentHelperOracel::getStudentHelperOracel));
        TableRegistry.insert(make_pair(make_pair(Oracel,GradesTable),GradesHelperOracel::getGradesHelperOracel));

    }
    StudentHelper *createStudentHelper()
    {
        return static_cast<StudentHelper *>( TableRegistry[make_pair(currentDbtype,StudentTable)]());
    }
    GradesHelper *createGradesHelper()
    {
        return static_cast< GradesHelper *>( TableRegistry[make_pair(currentDbtype,GradesTable)]());
    }
private:
    map<pair<DBType,DataType>,Func> TableRegistry;
    //当前的数据库类型,若需要切换数据库,仅需要修改这一出
    DBType currentDbtype = Access;
};
  1. 客户端调用

在这里插入图片描述

#include "student.h"
#include "grades.h"
#include "databasehelper.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //创建工厂类,切换数据库无需修改客户端
    DataBaseHelper *dbhelper = new DataBaseHelper ();

    cout << "*****对 Student 的操作*****"<<endl;
    Student student1;
    StudentHelper * studenthelper = dbhelper->createStudentHelper();
    studenthelper->saveStudent(student1);
    studenthelper->getStudent(0);

    cout << "*****对 Grades 的操作*****"<<endl;
    Grades grades1;
    GradesHelper * gradeshelper = dbhelper->createGradesHelper();
    gradeshelper->saveGrades(grades1);
    gradeshelper->getGrades(0);

    delete gradeshelper;
    delete studenthelper;
    delete dbhelper;

    return a.exec();
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值