当前位置: 首页 > news >正文

抽象工厂模式(大话设计模式)C/C++版本

抽象工厂模式

在这里插入图片描述

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15927110.html

#include <iostream>
using namespace std;// 抽象产品Department ,定义具体产品的公共接口
class Department
{
public:virtual ~Department() = default;virtual void Insert() = 0;virtual Department *GetDepartment() = 0;
};// 创建具体产品类SqlserDepartment, 定义生产的具体产品;
class SqlserDepartment : public Department
{
public:void Insert() override{cout << "在SQL Server 中给 Department 表增加一条记录!" << endl;}Department *GetDepartment() override{cout << "在SQL Server 中根据ID 得到 Department 表一条记录!" << endl;return nullptr;}
};// 创建具体产品类AccessDepartment, 定义生产的具体产品;
class AccessDepartment : public Department
{
public:void Insert() override{cout << "在 Access 中给 Department 表增加一条记录!" << endl;}Department *GetDepartment() override{cout << "在 Access 中根据ID 得到 Department 表一条记录!" << endl;return nullptr;}
};// 抽象产品User ,定义具体产品的公共接口
class User
{
public:virtual ~User() = default;virtual void Insert() = 0;virtual User *GetUser() = 0;
};// 创建具体产品类SqlserverUser, 定义生产的具体产品;
class SqlserverUser : public User
{
public:void Insert() override{cout << "在SQL Server 中给 User表增加一条记录!" << endl;}User *GetUser() override{cout << "在SQL Server 中根据ID 得到 User表一条记录!" << endl;return nullptr;}
};// 创建具体产品类AccessUser, 定义生产的具体产品;
class AccessUser : public User
{
public:void Insert() override{cout << "在 Access 中给 User表增加一条记录!" << endl;}User *GetUser() override{cout << "在 Access 中根据ID 得到 User表一条记录!" << endl;return nullptr;}
};// 抽象工厂,定义具体工厂的公共接口
class AbstractFactory
{
public:virtual ~AbstractFactory() = default;virtual User *CreateUser() = 0;virtual Department *CreateDepartment() = 0;
};// 创建具体工厂SqlServerFactory,定义创建对应具体产品实例的方法;
class SqlServerFactory : public AbstractFactory
{
public:User *CreateUser() override{return new SqlserverUser(); // 该工厂 生产的产品}Department *CreateDepartment() override{return new SqlserDepartment;}
};// 创建具体工厂AccessFactory,定义创建对应具体产品实例的方法;
class AccessFactory : public AbstractFactory
{
public:User *CreateUser() override{return new AccessUser(); // 该工厂 生产的产品}Department *CreateDepartment() override{return new AccessDepartment;}
};int main()
{// AbstractFactory *factory = new SqlServerFactory;AbstractFactory *factory = new AccessFactory;// 调用的是 AccessFactory 工厂,准备生产  SqlserverUser 产品User *iu = factory->CreateUser();iu->Insert();iu->GetUser();// 调用的是 AccessFactory 工厂,准备生产  AccessDepartment 产品Department *id = factory->CreateDepartment();id->Insert();id->GetDepartment();delete factory;delete iu;delete id;factory = nullptr;id = nullptr;id = nullptr;return 0;
}

C

#include <stdio.h>
#include <stdlib.h>// 抽象产品Department
typedef struct Department
{void (*Insert)(void *);struct Department *(*GetDepartment)(void *);
} Department;// 抽象产品User
typedef struct User
{void (*Insert)(void *);struct User *(*GetUser)(void *);
} User;// 抽象工厂
typedef struct AbstractFactory
{User *(*CreateUser)(void);Department *(*CreateDepartment)(void);
} AbstractFactory;// 具体产品SqlserDepartment
typedef struct SqlserDepartment
{Department base;
} SqlserDepartment;void SqlserDepartment_Insert(void *dept)
{printf("在SQL Server 中给 Department 表增加一条记录!\n");
}Department *SqlserDepartment_GetDepartment(void *dept)
{printf("在SQL Server 中根据ID 得到 Department 表一条记录!\n");return NULL;
}// 具体产品AccessDepartment
typedef struct AccessDepartment
{Department base;
} AccessDepartment;void AccessDepartment_Insert(void *dept)
{printf("在 Access 中给 Department 表增加一条记录!\n");
}Department *AccessDepartment_GetDepartment(void *dept)
{printf("在 Access 中根据ID 得到 Department 表一条记录!\n");return NULL;
}// 具体产品SqlserverUser
typedef struct SqlserverUser
{User base;
} SqlserverUser;void SqlserverUser_Insert(void *user)
{printf("在SQL Server 中给 User表增加一条记录!\n");
}User *SqlserverUser_GetUser(void *user)
{printf("在SQL Server 中根据ID 得到 User表一条记录!\n");return NULL;
}// 具体产品AccessUser
typedef struct AccessUser
{User base;
} AccessUser;void AccessUser_Insert(void *user)
{printf("在 Access 中给 User表增加一条记录!\n");
}User *AccessUser_GetUser(void *user)
{printf("在 Access 中根据ID 得到 User表一条记录!\n");return NULL;
}// 具体工厂SqlServerFactory
typedef struct SqlServerFactory
{AbstractFactory base;
} SqlServerFactory;User *SqlServerFactory_CreateUser(void *unused)
{SqlserverUser *user = (SqlserverUser *)malloc(sizeof(SqlserverUser));user->base.Insert = SqlserverUser_Insert;user->base.GetUser = SqlserverUser_GetUser;return (User *)user;
}Department *SqlServerFactory_CreateDepartment(void *unused)
{SqlserDepartment *dept = (SqlserDepartment *)malloc(sizeof(SqlserDepartment));dept->base.Insert = SqlserDepartment_Insert;dept->base.GetDepartment = SqlserDepartment_GetDepartment;return (Department *)dept;
}// 具体工厂AccessFactory
typedef struct AccessFactory
{AbstractFactory base;
} AccessFactory;User *AccessFactory_CreateUser()
{AccessUser *user = (AccessUser *)malloc(sizeof(AccessUser));user->base.Insert = AccessUser_Insert;user->base.GetUser = AccessUser_GetUser;return (User *)user;
}Department *AccessFactory_CreateDepartment()
{AccessDepartment *dept = (AccessDepartment *)malloc(sizeof(AccessDepartment));dept->base.Insert = AccessDepartment_Insert;dept->base.GetDepartment = AccessDepartment_GetDepartment;return (Department *)dept;
}int main()
{AbstractFactory *factory = (AbstractFactory *)malloc(sizeof(AccessFactory));((AccessFactory *)factory)->base.CreateUser = AccessFactory_CreateUser;((AccessFactory *)factory)->base.CreateDepartment = AccessFactory_CreateDepartment;User *iu = factory->CreateUser();iu->Insert(iu);iu->GetUser(iu);Department *id = factory->CreateDepartment();id->Insert(id);id->GetDepartment(id);free(factory);free(iu);free(id);return 0;
}

总结

在工厂方法模式的基础上,在对应的工厂类中新增了相关产品的创建函数。(其实并不是很方便!!)

扩展:
简单工厂模式似乎更简便点,但是switch部分实在是破坏了开闭原则,可以使用“反射”(即动态识别类型)

C++可以使用静态函数指针数组来实现
参考:https://blog.csdn.net/klarclm/article/details/7352101

相关文章:

抽象工厂模式(大话设计模式)C/C++版本

抽象工厂模式 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15927110.html #include <iostream> using namespace std;// 抽象产品Department ,定义具体产品的公共接口 class Department { public:virtual ~Department() default;virtual void Insert()…...

springboot宠物医院信息管理系统-计算机毕业设计源码04164

摘 要 现如今在中国&#xff0c;随着人民生活质量的逐渐提高&#xff0c;以及人民群众消费能力的日渐增长&#xff0c;各种各样的家养小动物&#xff0c;已经逐渐成为人类越来越亲密的生活伴侣。并且&#xff0c;现如今社会竞争及其激烈&#xff0c;人们的生活节奏越发急促、紧…...

Leetcode Hot100之哈希表

1. 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现思路…...

Vision Transformer with Sparse Scan Prior

摘要 https://arxiv.org/pdf/2405.13335v1 In recent years, Transformers have achieved remarkable progress in computer vision tasks. However, their global modeling often comes with substantial computational overhead, in stark contrast to the human eye’s eff…...

笔记-python 中BeautifulSoup入门

在前面的例子用&#xff0c;我用了BeautifulSoup来从58同城抓取了手机维修的店铺信息&#xff0c;这个库使用起来的确是很方便的。本文是BeautifulSoup 的一个详细的介绍&#xff0c;算是入门把。文档地址&#xff1a;http://www.crummy.com/software/BeautifulSoup/bs4/doc/ …...

Tomcat Websocket应用实例研究

概述 本文介绍了如何根据Tomcat给出的websocket实例&#xff0c;通过对实例的学习&#xff0c;定制自己基于websocket的应用。 环境及版本&#xff1a; Ubuntu 22.04.4 LTSApache Tomcat/10.1.20openjdk 11.0.23 2024-04-16浏览器&#xff1a;Chrome 相关资源及链接 Class…...

leetcode-11-二叉树前中后序遍历以及层次遍历

一、递归版 前序遍历 &#xff08;先根遍历&#xff09; 中左右 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result new ArrayList<Integer>();preorder(root, result);return result;}public void preorder…...

Python基础学习笔记(十一)——集合

目录 一、集合的介绍与创建二、集合的存储原理三、元素的修改1. 添加元素2. 删除元素 四、集合的运算五、集合的判定 一、集合的介绍与创建 集合&#xff08;set&#xff09;&#xff0c;一种可变、无序、不重复的数据结构&#xff0c;由大括号{}内、用逗号分隔的一组元素组成。…...

FineReport

1.FineReport 官网 &#xff1a;FineReport产品简介- FineReport帮助文档 - 全面的报表使用教程和学习资料 下载地址 免费下载FineReport - FineReport报表官网 FineReport是一款用于报表制作&#xff0c;分析和展示的工具。 普通模板&#xff1a;是 FineReport 最常用&#xf…...

嵌入式就业前景好么

嵌入式就业前景在当前环境下是较为乐观的&#xff0c;以下是对嵌入式就业前景的详细分析&#xff1a; 广泛应用领域&#xff1a;嵌入式系统广泛应用于智能家居、医疗设备、航空航天等领域。随着物联网&#xff08;IoT&#xff09;的快速发展&#xff0c;预计到2024年&#xff…...

为啥找对象千万别找大厂男,还好我不是大厂的。。

网上看到一大厂女员工发文说&#xff1a;找对象千万别找大厂男&#xff0c;理由说了一大堆&#xff0c;无非就是大厂男为了逃避带娃&#xff0c;以加班为由宁愿在工位上玩游戏也不愿回家。当然这种观点有的人赞同有的人反对。 网友精彩评论&#xff1a; --------------下面是今…...

如何查看k8s中service的负载均衡策略

在Kubernetes中&#xff0c;Service的负载均衡策略一般由kube-proxy负责&#xff0c;kube-proxy使用iptables或IPVS规则进行负载均衡。默认情况下&#xff0c;kube-proxy使用的是轮询&#xff08;Round Robin&#xff09;策略&#xff0c;但是在使用IPVS模式时&#xff0c;可以…...

Linux-DNS域名解析服务01

BIND 域名服务基础 1、DNS&#xff08;Domain Name System&#xff09;系统的作用及类型 整个 Internet 大家庭中连接了数以亿计的服务器、个人主机&#xff0c;其中大部分的网站、邮件等服务器都使用了域名形式的地址&#xff0c;如 www.google.com、mail.163.com 等。很显然…...

[c++刷题]贪心算法.N01

题目如上: 首先通过经验分析&#xff0c;要用最少的减半次数&#xff0c;使得数组总和减少至一半以上&#xff0c;那么第一反应就是每次都挑数组中最大的数据去减半&#xff0c;这样可以是每次数组总和值减少程度最大化。 代码思路:利用大根堆去找数据中的最大值&#xff0c;…...

推荐常用的三款源代码防泄密软件

三款源代码防泄密软件——安秉源代码加密、Virbox Protector 和 MapoLicensor——确实各自在源代码保护的不同方面有其专长。这些软件可以满足企业对于源代码保护的三大需求&#xff1a;防止泄露、防止反编译和防止破解。 安秉源代码加密&#xff1a; 专注于源代码文件的加密&…...

Android 13 高通设备热点低功耗模式(2)

前言 之前写过一篇文章:高通热点被IOS设备识别为低数据模式,该功能仿照小米的低数据模式写的,散发的热点可以达到被IOS和小米设备识别为低数据模式。但是发现IOS设备如果后台无任何网络请求的时候,息屏的状态下过一会,会自动断开热点的连接。 分析 抓取设备的热点相关的…...

web前端任职条件:全面解析

web前端任职条件&#xff1a;全面解析 在当今数字化快速发展的时代&#xff0c;Web前端技术已经成为互联网行业不可或缺的一部分。作为一名Web前端开发者&#xff0c;需要具备哪些任职条件呢&#xff1f;本文将从四个方面、五个方面、六个方面和七个方面为您深入剖析。 四个方…...

分析医药零售数据该用哪个BI数据可视化工具?

数据是企业决策的重要依据&#xff0c;可以用于现代企业大数据可视化分析的BI工具有很多&#xff0c;各有各擅长的领域。那么哪个BI数据可视化工具分析医药零售数据又好又快&#xff1f; 做医药零售数据分析首推奥威BI数据可视化工具&#xff01; 奥威BI数据可视化工具做医药…...

如何使用芯片手册做软件开发?

在阅读和利用芯片手册进行软件开发时&#xff0c;你应该关注以下几个关键点&#xff1a; 引脚功能&#xff1a;了解芯片上每个引脚的功能&#xff0c;包括它们可以被配置为输入还是输出&#xff0c;以及它们支持的特殊功能&#xff0c;如模拟输入、PWM输出、中断等。 寄存器映…...

基于深度学习的文本翻译

基于深度学习的文本翻译 基于深度学习的文本翻译&#xff0c;通常称为神经机器翻译&#xff08;Neural Machine Translation, NMT&#xff09;&#xff0c;是近年来在自然语言处理&#xff08;NLP&#xff09;领域取得显著进展的技术。NMT通过使用深度神经网络来自动学习和翻译…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...