抽象工厂模式与单件模式C++混合实现

2023-05-16

在这里插入图片描述

抽象工厂

当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

单件模式

Singleton就是确保一个类只有唯一的一个实例。Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton模式,最常见的比如我们希望整个应用程序中只有一个连接数据库的Connection实例;又比如要求一个应用程序中只存在某个用户数据结构的唯一实例。我们都可以通过应用Singleton模式达到目的。
具体请看:
http://www.omegaxyz.com/2019/03/19/design-pattern-singleton/

实例

该公司数据库拥有三张表,分别是用户表、部门表和项目表。每张表的操作都支持查询和添加功能。数据库支持MySQL和SQL Server两种。结合抽象工厂模式和单件模式给出该系统的模拟代码。

在抽象工厂模式中,一个应用里一般每个产品只需要一个具体工厂的实例,因此,工厂通常最好用单件模式实现。实验要求结合抽象工厂模式和单件模式,模拟公司数据库创建过程。

UML

在这里插入图片描述

C++代码

#include<iostream>
using namespace std;
 
 
class User{
    int id;
};
 
class Department{
    int id;
};
 
class Project{
    int id;
};
 
 
 
 
class IUser{
public:
    virtual void Insert(User* user) = 0;
    virtual User* GetUser(int id) = 0;
};
 
class IDepartment{
public:
    virtual void Insert(Department* department) = 0;
    virtual Department* GetDepartment(int id) = 0;
};
 
class IProject{
public:
    virtual void Insert(Project* project) = 0;
    virtual Project* GetProject(int id) = 0;
};
 
class IFactory{
public:
    virtual ~IFactory(){cout<<"抽象工厂实例删除!"<<endl;}
    virtual IUser* CreateUser()=0;
    virtual IDepartment* CreateDepartment()=0;
    virtual IProject* CreateProject()=0;    
};
 
class SqlserverUser: public IUser{
public:
    void Insert(User* user){
        cout<<"增加一个用户"<<endl;
    }
    User* GetUser(int id){
        cout<<"得到一个用户"<<endl;
        return NULL;
    }
};
 
class SqlserverDepartment: public IDepartment{
public:
    void Insert(Department* department){
        cout<<"增加一个部门"<<endl;
    }
    Department* GetDepartment(int id){
        cout<<"得到一个部门"<<endl;
        return NULL;
    }
};
 
class SqlserverProject: public IProject{
public:
    void Insert(Project* project){
        cout<<"增加一个项目"<<endl;
    }
    Project* GetProject(int id){
        cout<<"得到一个项目"<<endl;
        return NULL;
    }
};
 
class MysqlUser: public IUser{
public:
    void Insert(User* user){
        cout<<"增加一个用户"<<endl;
    }
    User* GetUser(int id){
        cout<<"得到一个用户"<<endl;
        return NULL;
    }
};
 
class MysqlDepartment: public IDepartment{
public:
    void Insert(Department* department){
        cout<<"增加一个部门"<<endl;
    }
    Department* GetDepartment(int id){
        cout<<"得到一个部门"<<endl;
        return NULL;
    }
};
 
class MysqlProject: public IProject{
public:
    void Insert(Project* project){
        cout<<"增加一个项目"<<endl;
    }
    Project* GetProject(int id){
        cout<<"得到一个项目"<<endl;
        return NULL;
    }
};
 
 
class SqlserverFactory: public IFactory{
public:
    ~SqlserverFactory(){cout<<"SQL Server抽象工厂实例删除!"<<endl;}
    IUser* CreateUser(){
        return new SqlserverUser();
    }
    IDepartment* CreateDepartment(){
        return new SqlserverDepartment();
    }
    IProject* CreateProject(){
        return new SqlserverProject();
    }
    static IFactory *GetInstance(){
        if (factory == NULL ){
                return new SqlserverFactory();
                cout<<"抽象工厂实例生成!"<<endl;
        
        }else cout<<"Error, 抽象工厂实例已有!"<<endl;
        return factory;
    }
private:
    
    SqlserverFactory(){}
    static SqlserverFactory* factory;
};
SqlserverFactory* SqlserverFactory::factory = NULL;
 
 
 
class MysqlFactory: public IFactory{
public:
    ~MysqlFactory(){cout<<"SQL Server抽象工厂实例删除!"<<endl;}
    IUser* CreateUser(){
        return new MysqlUser();
    }
    IDepartment* CreateDepartment(){
        return new MysqlDepartment();
    }
    IProject* CreateProject(){
        return new MysqlProject();
    }
    static IFactory *GetInstance(){
        if (factory == NULL ){
            cout<<"抽象工厂实例生成!"<<endl;
            factory =  new MysqlFactory();
                
        }else cout<<"Error, 抽象工厂实例已有!"<<endl;
        return factory;
    }
private:
    MysqlFactory(){}
    static MysqlFactory* factory;
};
MysqlFactory* MysqlFactory::factory = NULL;
 
int main(){
    User* user = new User();
    Department* dept = new Department();
    Project* pro = new Project();
 
 
    cout<<endl<<"MySQL"<<endl;
    IFactory *factory1 = MysqlFactory::GetInstance();
    IFactory *factory2 = MysqlFactory::GetInstance();
    //生成第二个失败
    IUser* iu = factory1->CreateUser();
    iu->Insert(user);
    iu->GetUser(1);
    
    IDepartment* idept = factory1->CreateDepartment();
    idept->Insert(dept);
    idept->GetDepartment(1);
 
    IProject* ipro = factory1->CreateProject();
    ipro->Insert(pro);
    ipro->GetProject(1);
 
    cout<<endl<<"SQL Server"<<endl;
    IFactory *factory12 = MysqlFactory::GetInstance();
    IFactory *factory22 = MysqlFactory::GetInstance();
    //生成第二个失败
    IUser* iu2 = factory12->CreateUser();
    iu->Insert(user);
    iu->GetUser(1);
    
    IDepartment* idept2 = factory12->CreateDepartment();
    idept->Insert(dept);
    idept->GetDepartment(1);
 
    IProject* ipro2 = factory12->CreateProject();
    ipro->Insert(pro);
    ipro->GetProject(1);
    return 0;
}

结果

在这里插入图片描述
注意第二行是再次生成一个MySQL的工厂,但是由于只能有一个,因此不能再次创建。

总结

注意使用单件模式写MySQL和SQL Server的具体工厂时,只能对自身单件,即生成一个MySQL工厂时,不能再次生成第二个MySQL工厂,但是可以生成SQL Server工厂。

当使用单件模式时,具体工厂的构造函数需要放在private中,这样客户端不能随意创建多个工厂。在public中需要增加getInstance函数用来判断是否生成了工厂,如果存在,则不能创建第二个,注意这是static类型。

具体工厂的指针需要在类外部全局部分进行初始化为NULL。

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2019 • OmegaXYZ-版权所有 转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抽象工厂模式与单件模式C++混合实现 的相关文章

  • Android 使用字符串动态获取资源ID

    android文件中每个文件都有一个ID xff0c 如下图所示 xff0c 左边的0x7f060000即是文件的ID xff1a 如果我们想在代码中获取这个文件的ID应该使用高效率的反射机制 xff0c 可以新建一个Java类代码如下 x
  • wxpython画表格代码

    wxPython是Python语言的一套优秀的GUI图形库 允许Python程序员很方便的创建完整的 功能键全的GUI用户界面 wxPython是作为优秀的跨平台GUI库wxWidgets的Python封装和Python模块的方式提供给用户
  • 数据库c3p0配置SQL Server与MySQL

    C3P0是一个开源的JDBC连接池 xff0c 它实现了数据源和JNDI绑定 xff0c 支持JDBC3规范和JDBC2的标准扩展 目前使用它的开源项目有Hibernate xff0c Spring等 SQL Server配置 xff1a
  • JSP连数据库登录检查用户名和密码模板

    JSP全名为Java Server Pages xff0c 中文名叫java服务器页面 xff0c 其根本是一个简化的Servlet设计 xff0c 它是由Sun Microsystems公司倡导 许多公司参与一起建立的一种动态网页技术标准
  • 基于移动设备与CNN的眼动追踪技术简介

    眼动追踪是一项科学应用技术 xff0c 用户无需与交互设备物理接触即可发送信息与接收反馈 从原理上看 xff0c 眼动追踪主要是研究眼球运动信息的获取 建模和模拟 xff0c 用途颇广 而获取眼球运动信息的设备除了红外设备之外 xff0c
  • 递归下降实现LL(1)文法分析C语言与Python实现

    对文法G的句子进行确定的自顶向下语法分析的充分必要条件是 xff0c G的任意两个具有相同左部的产生式A gt 满足下列条件 xff1a xff08 1 xff09 如果 均不能推导出 xff0c 则 FIRST FIRST 61 xff0
  • Ubuntu下gcc的安装

    sudo apt get build dep gcc
  • PyTorch入门

    PyTorch入门 PyTorch 是一个建立在 Torch 库之上的 Python 包 xff0c 旨在加速深度学习应用 PyTorch 提供一种类似 NumPy 的抽象方法来表征张量 xff08 或多维数组 xff09 xff0c 它可
  • 华氏451

    2015年12月21日 xff0c 因特网工程指导组 IETF 批准了全新HTTP状态错误代码 451 xff0c 这个代码的官方释义为 由于法律原因而不可用 451 数字来源于 1953 年由美国作家雷 布莱伯利所著的反乌托邦小说 华氏
  • 蚁群算法最短路径规划多出口情况及问题答疑

    最近好多人问我蚁群算法最短路径规划如何设置多出口情况 xff0c 原来2019年美赛D题 拯救卢浮宫 需要用到 本人没有看过美赛的题目 xff0c 下面给出一些不成熟的代码 蚁群算法简介 xff1a 蚁群算法最早是由Marco Dorigo
  • 反世代距离评价指标IGD

    反世代距离评价指标 Inverted Generational Distance IGD 是一个综合性能评价指标 它主要通过计算每个在真实 Pareto前沿面上的点 个体 到算法获取的个体集合之间的最小距离和 xff0c 来评价算法的收敛性
  • 遗传算法解决TSP问题MATLAB实现(详细)

    问题定义 xff1a 巡回旅行商问题 给定一组n个城市和俩俩之间的直达距离 xff0c 寻找一条闭合的旅程 xff0c 使得每个城市刚好经过一次且总的旅行距离最短 TSP问题也称为货郎担问题 xff0c 是一个古老的问题 最早可以追溯到17
  • 二叉树遍历的转换C++实现

    二叉树的遍历分为以下三种 xff1a 先序遍历 xff1a 遍历顺序规则为 根左右 中序遍历 xff1a 遍历顺序规则为 左根右 后序遍历 xff1a 遍历顺序规则为 左右根 什么是 根左右 就是先遍历根 xff0c 再遍历左节点 xff0
  • Java数据存取对象(DAO)

    什么是DAO DAO xff08 Data Access Object xff09 顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象 xff0c 在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作 在实际的开发中 xff
  • 经典蝙蝠算法MATLAB实现

    为什么会有这么多基于群智能的算法 xff0c 蚁群 粒子群 鱼群 烟花 炮竹 猪群 牛群 马群 羊群 猴群 鸡群 算法 xff1f xff1f xff1f xff1f xff1f xff1f 黑人问号 jpg 蝙蝠算法 BA 是 Yang
  • 计算机领域顶级会议、期刊、人物与国家排名2019

    原文地址 xff1a 最近浏览到一个网站 xff1a http www guide2research com 这是一个根据谷歌学术排名的计算机领域各类会议 学术期刊 人物 国家 组织的排名查询网站 时间2019年3月 会议 按照Hindex
  • 基于迭代局部搜索和随机惯性权重的BA算法MATLAB实现(ILSSIWBA)

    BA算法简介 http www omegaxyz com 2019 02 12 ba matlab 该论文修改 作者在原有BA算法上进行3个修改 跳出局部最优 xff08 扰动个体 xff09 使得算法变得稳定脉搏和响度修改 xff0c 平
  • Ubuntu下pip的安装与升级

    安装 pip2 sudo apt get install python pip python dev build essential wukai 64 wukai sudo apt install python span class hlj
  • PyQt5多线程刷新界面防假死

    在做GUI界面时我们希望后台任务能够与UI分开 xff0c 在PyQt中 xff0c 主线程用来重绘界面 而子线程里边的实时处理结果需要反馈到界面 xff0c 子线程里边不能执行界面更新操作 wxpython多线程刷新界面转到 http w

随机推荐

  • NSGA2算法中文详解与MATLAB实现整理

    NSGA2算法 NSGA II多目标遗传算法概述 http www omegaxyz com 2017 04 14 nsga iiintro NSGA2算法MATLAB实现 xff08 能够自定义优化函数 xff09 http www om
  • 对极大似然估计的理解

    参数估计 xff08 parameter estimation xff09 统计推断的一种 根据从总体中抽取的随机样本来估计总体分布中未知参数的过程 从估计形式看 xff0c 区分为点估计与区间估计 xff1a 从构造估计量的方法讲 xff
  • 动态规划——最大整除子集C++

    来自LeetCode 368 描述 给出一个由无重复的正整数组成的集合 xff0c 找出其中最大的整除子集 xff0c 子集中任意一对 Si xff0c Sj 都要满足 xff1a Si Sj 61 0 或 Sj Si 61 0 如果有多个
  • HyperVolume多目标评价指标概述

    提出 Hypervolume 指标评价方法最早是由 Zitzler 等提出 xff0c 它表示由解集中的个体与参考点在目标空间中所围成的超立方体的体积 评价标准 Hypervolume 指 标 评 价 方 法 是 一 种 与 Pareto
  • 三路快排C++实现与应用

    本文共467个字 xff0c 预计阅读时间需要2分钟 三路快排是快速排序算法的升级版 xff0c 用来处理有大量重复数据的数组 主要思想是选取一个key xff0c 小于key的丢到左边 xff0c 大于key的丢到右边 xff0c 递归实
  • Wilcoxon秩和检验简介与MATLAB实现

    Wilcoxon秩和检验 rank sum test xff0c 有时也叫Mann Whitney U检验 xff0c 是另一类非参数检验方法 xff0c 它们不对数据分布作特殊假设 xff0c 因而能适用于更复杂的数据分布情况 适用性 x
  • FatMouse’ Trade

    简介 贪心算法 xff08 又称贪婪算法 xff09 是指 xff0c 在对问题求解时 xff0c 总是做出在当前看来是最好的选择 也就是说 xff0c 不从整体最优上加以考虑 xff0c 他所做出的是在某种意义上的局部最优解 贪心算法不是
  • 算法复杂度与NP问题

    引言 美剧 基本演绎法 S2E2中 xff0c 两位研究 NP 问题的数学家被谋杀了 xff0c 凶手是同行 xff0c 因为被害者即将证明 P 61 NP 问题 假设人类证明了P 61 NP 是真的 xff0c 那么就会有一个算法 xff
  • 素数筛C++

    埃拉托斯特尼筛法 xff08 sieve of Eratosthenes xff09 是古希腊数学家埃拉托斯特尼发明的计算素数的方法 对于求解不大于n的所有素数 xff0c 我们先找出sqrt n 内的所有素数p1到pk xff0c 其中k
  • ubuntu安装mysql-server环境解决无穷依赖问题

    问题 ubuntu14 04 3安装mysql时报错 xff1a sudo apt get install mysql server mysql client 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有
  • Levenshtein编辑距离C++实现

    简介 Levenshtein Distance是1965年由苏联数学家Vladimir Levenshtein发明的 Levenshtein Distance也被称为编辑距离 xff08 Edit Distance xff09 在信息论和计
  • 红黑树简介与C++应用

    简介 红黑树 xff08 Red Black Tree xff09 是一种自平衡二叉查找树 xff0c 是在计算机科学中用到的一种数据结构 xff0c 典型的用途是实现关联数组 它是在1972年由Rudolf Bayer发明的 xff0c
  • 碰撞域与广播域的区别

    在说到碰撞域 xff08 冲突域 xff09 和广播域之前 xff0c 首先要介绍一下三个网络互连设备 集线器 交换机和路由器 集线器 集线器是工作在物理层的设备 xff0c 当他收到数据以后就把这个数据复制复制以后就把这个数据象所有的接口
  • WordPress数据库error establishing a database connection错误

    本文共777个字 xff0c 预计阅读时间需要2分钟 作为一个买不起大型服务器只能用阿里云学生机的站长 xff0c 经常遇到error establishing a database connection错误 这是一种建立数据库连接时的错误
  • 基于稀疏大规模矩阵的多目标进化算法简介

    简介 可以看到本文的特色图片是个极度稀疏连接的神经网络 xff0c 它是由我们即将介绍论文中的算法SparseEA得到的 此篇论文是BIMK的田野 张兴义等人发表在IEEE Transactions on Evolutionary Comp
  • 回溯法——素数环C++实现

    本文共928个字 xff0c 预计阅读时间需要3分钟 回溯法简介 回溯法按深度优先策略搜索问题的解空间树 首先从根节点出发搜索解空间树 xff0c 当算法搜索至解空间树的某一节点时 xff0c 先利用剪枝函数判断该节点是否可行 xff08
  • Prime Path素数筛与BFS动态规划

    本文共2053个字 xff0c 预计阅读时间需要6分钟 BFS BFS xff0c 其英文全称是Breadth First Search BFS并不使用经验法则算法 从算法的观点 xff0c 所有因为展开节点而得到的子节点都会被加进一个先进
  • C++读取和写入文件(fstream等)

    本文共321个字 xff0c 预计阅读时间需要1分钟 2019年7月非常忙 xff0c 这大概是这个月的第一篇吧 某高校机试需要从文件中读取数据并将数据写入到文件中 完成这一操作需要用到fstream模块 xff0c 网上一堆资料 xff0
  • 并查集应用——PAT甲级2019春季

    并查集适用问题举例 1 已知 xff0c 有n个人和m对好友关系 2 如果两个人是直接的或者间接的好友 xff08 好友的好友的好友 xff09 xff0c 那么他们属于一个集合 xff0c 就是一个朋友圈中 3 写出程序 xff0c 求这
  • 抽象工厂模式与单件模式C++混合实现

    抽象工厂 当每个抽象产品都有多于一个的具体子类的时候 xff0c 工厂角色怎么知道实例化哪一个子类呢 xff1f 比如每个抽象产品角色都有两个具体产品 抽象工厂模式提供两个具体工厂角色 xff0c 分别对应于这两个具体产品角色 xff0c