工厂方法模式(大话设计模式)C/C++版本
工厂方法模式
C++
参考:https://www.cnblogs.com/Galesaur-wcy/p/15926711.html
#include <iostream>
#include <memory>
using namespace std;// 运算类
class Operation
{
private:double _NumA;double _NumB;public:void SetNumA(){cout << "Enter a double number: ";if (!(cin >> _NumA))throw "It must be a number";}double GetNumA(){return _NumA;}void SetNumB(){cout << "Enter a double number: ";if (!(cin >> _NumB))throw "It must be a number";}double GetNumB(){return _NumB;}virtual double GetResult(){int result = 0;return result;}
};class OperationAdd : public Operation
{
public:double GetResult(){double result = GetNumA() + GetNumB();return result;}
};class OperationSub : public Operation
{
public:double GetResult(){double result = GetNumA() - GetNumB();return result;}
};class OperationMul : public Operation
{
public:double GetResult(){double result = GetNumA() * GetNumB();return result;}
};class OperationDiv : public Operation
{
public:double GetResult(){if (GetNumB() == 0){throw "The divisor cannot be 0";}double result = GetNumA() / GetNumB();return result;}
};class Factory
{
public:virtual Operation *CreatOperation() = 0;
};class AddFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationAdd();}
};class SubFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationSub();}
};class MulFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationMul();}
};class DivFactory : public Factory
{
public:Operation *CreatOperation(){return new OperationDiv();}
};/* 封装一下用户选择工厂创建的过程(属于客户端代码) */
Factory * CreatFactory(char operator_type)
{switch (operator_type){case '+':return new AddFactory;break;case '-':return new SubFactory;break;case '*':return new MulFactory;break;case '/':return new DivFactory;break;default:throw "Error input operator!";break;}return nullptr;
}int main()
{cout << "Choose an operation:";char operator_char;cin >> operator_char;try{//unique_ptr<Factory> fac = unique_ptr<Factory>(CreatFactory(operator_char));//智能指针更安全Factory* fac = CreatFactory(operator_char);//unique_ptr<Operation> oper = unique_ptr<Operation>(fac->CreatOperation());Operation* oper = fac->CreatOperation();oper->SetNumA();oper->SetNumB();cout << "result is: " << oper->GetResult() << endl;}catch (const char *err){cerr << err << endl;return -1;}return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>typedef struct Operation
{double NumA;double NumB;double (*GetResult)(struct Operation *);void (*SetNumA)(struct Operation *);void (*SetNumB)(struct Operation *);
} Operation;typedef struct OperationAdd
{Operation base; // 设置为第一个成员属性,模拟继承
} OperationAdd;typedef struct OperationSub
{Operation base;
} OperationSub;typedef struct OperationMul
{Operation base;
} OperationMul;typedef struct OperationDiv
{Operation base;
} OperationDiv;double OperationAddGetResult(struct Operation *op)
{OperationAdd *add = (OperationAdd *)op;return add->base.NumA + add->base.NumB;
}double OperationSubGetResult(struct Operation *op)
{OperationSub *sub = (OperationSub *)op;return sub->base.NumA - sub->base.NumB;
}double OperationMulGetResult(struct Operation *op)
{OperationMul *mul = (OperationMul *)op;return mul->base.NumA * mul->base.NumB;
}double OperationDivGetResult(struct Operation *op)
{OperationDiv *div = (OperationDiv *)op;if (div->base.NumB == 0){fputs("The divisor cannot be 0\n", stderr);exit(EXIT_FAILURE);}return div->base.NumA / div->base.NumB;
}typedef struct Factory
{Operation* (*CreatOperation)();
}Factory;typedef struct FactoryAdd
{Factory base;
} FactoryAdd;typedef struct FactorySub
{Factory base;
} FactorySub;typedef struct FactoryMul
{Factory base;
} FactoryMul;typedef struct FactoryDiv
{Factory base;
} FactoryDiv;void SetNumA(Operation *ope)
{printf("Enter a double number: ");if (scanf("%lf", &ope->NumA) != 1){fputs("It must be a number\n", stderr);exit(EXIT_FAILURE);}
}void SetNumB(Operation *ope)
{printf("Enter a double number: ");if (scanf("%lf", &ope->NumB) != 1){fputs("It must be a number\n", stderr);exit(EXIT_FAILURE);}
}Operation *CreatOperationAdd()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationAddGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationSub()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationSubGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationMul()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationMulGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Operation *CreatOperationDiv()
{Operation *op = malloc(sizeof(Operation));op->GetResult = OperationDivGetResult;op->SetNumA = SetNumA;op->SetNumB = SetNumB;return op;
}Factory *CreateFactory(char op)
{Factory *fac = NULL;switch (op){case '+':fac = malloc(sizeof(FactoryAdd));fac->CreatOperation = CreatOperationAdd;break;case '-':fac = malloc(sizeof(FactorySub));fac->CreatOperation = CreatOperationSub;break;case '*':fac = malloc(sizeof(FactoryMul));fac->CreatOperation = CreatOperationMul;break;case '/':fac = malloc(sizeof(FactoryDiv));fac->CreatOperation = CreatOperationDiv;break;default:fputs("Error input operator!\n", stderr);return NULL;}return fac;
}int main()
{printf("Choose an operation: ");char operator_char = getchar();Factory* fac = CreateFactory(operator_char);Operation *oper = fac->CreatOperation();if (!oper)return EXIT_FAILURE;oper->SetNumA(oper);oper->SetNumB(oper);printf("Result is: %f\n", oper->GetResult(oper));free(oper);return 0;
}
对比简单工厂模式
简单工厂模式例子
- 给四种运算新建了四个具体工厂类
- 将简单工厂类模式中的工厂创建逻辑判断,移到了客户端代码中
工厂方法模式这样做的目的就是:对创建工厂类的修改关闭,对具体工厂类的扩展开放。
思维思路:
- 简单工厂类中的创建工厂类中直接与具体的运算符号产生了依赖,不易于扩展(后期增加运算符,得直接修改工厂类)。
- 为了降低耦合,根据依赖倒置的原则(细节依赖抽象),将创建工厂类的分支判断直接改成对应的具体工厂类。
相关文章:
工厂方法模式(大话设计模式)C/C++版本
工厂方法模式 C 参考:https://www.cnblogs.com/Galesaur-wcy/p/15926711.html #include <iostream> #include <memory> using namespace std;// 运算类 class Operation { private:double _NumA;double _NumB;public:void SetNumA(){cout << &…...

[NCTF 2018]flask真香
打开题目后没有提示框,尝试扫描后也没有什么结果,猜想是ssti。所以尝试寻找ssti的注入点并判断模版。 模版判断方式: 在url地址中输入{7*7} 后发现不能识别执行。 尝试{{7*7}} ,执行成功,继续往下走注入{{7*7}},如果执…...

性能测试3【搬代码】
1.Linux服务器性能分析命令及详解 2.GarafanainfluxDB监控jmeter数据 3.GarafanaPrometheus监控服务器和数据库性能 4.性能瓶颈分析以及性能调优方案详解 一、无界面压测时, top load average:平均负载 htop 二、Garafana监控平台 传统项目:centosphpm…...
<tesseract><opencv><Python>基于python和opencv,使用ocr识别图片中的文本并进行替换
前言 本文是在python中,利用opencv处理图片,利用tesseractOCR来识别图片中的文本并进行替换的一种实现方法。 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、opencv、tesseractOCR 代码介绍 本文程序功能实现,主要依赖于tesseractOCR这个库,…...

海南云亿商务咨询有限公司解锁抖音电商新纪元
在当今数字化浪潮中,抖音电商以其独特的魅力和强大的用户基础,迅速成为企业营销的新宠。海南云亿商务咨询有限公司,作为专注于抖音电商服务的领先企业,凭借专业的团队和丰富的经验,为众多企业提供了高效、精准的电商服…...
arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例)
arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例) 搞了好久搞得头疼哎 1、准备服务器UOS服务器 准备服务IP 这里是192.168.1.100 1.1、安装程序 yum install -y dhcp tftp tftp-server xinetd nfs-utils rpcbind 2、修改配置 2.1、修改dhcpd.c…...

SpringBoot 实现 阿里云语音通知(SingleCallByTts)
目录 一、准备工作1.开通 阿里云语音服务2.申请企业资质3.创建语音通知模板,审核通过4.调用API接口---SingleCallByTts5.调试API接口---SingleCallByTts 二、代码实现1.导入依赖 com.aliyun:aliyun-java-sdk-dyvmsapi:3.0.22.创建工具类,用于发送语音通知…...

IDEA 连接GitHub仓库并上传项目(同时解决SSH问题)
目录 1 确认自己电脑上已经安装好Git 2 添加GitHub账号 2.1 Setting -> 搜索GitHub-> ‘’ -> Log In with Token 2.2 点击Generate 去GitHub生成Token 2.3 勾选SSH后其他不变直接生成token 2.4 然后复制token添加登录账号即可 3 点击导航栏中VCS -> Create…...

vue/react/js 常用的原生获取当前页面的url网址的相关方法
目录 第一章 场景 第二章 总结 第一章 场景 最近实现需求时遇到这么一种情况: 本地url —— 线上url —— 需求:需要将token清除掉 注意事项:token不是#/后面的参数,说明并不是我们前端返回的,vue路由的方法使用不…...
java-final 关键字
## Java中的final关键字 ### 1. final关键字的基本概念 final是Java中一个非常重要的关键字,用于声明常量、阻止继承和重写,确保类、方法和变量的不可变性。具体来说,final关键字可以用来修饰类、方法和变量(包括成员变量和局部…...

ARM32开发--IIC软实现
知不足而奋进 望远山而前行 目录 文章目录 前言 开发流程 GD32F4软件I2C初始化 GD32F4软件I2C引脚功能 写操作 读操作 总结 前言 在嵌入式系统开发中,软件实现的I2C通信协议扮演着至关重要的角色。本文将深入探讨如何在GD32F4系列微控制器上实现软件I2C功能…...
在有向无环图(DAG)中实现拓扑排序与最短路径和最长路径算法
有向无环图(DAG)是一类非常重要的图结构,广泛应用于任务调度、数据依赖分析等领域。本文将介绍如何在DAG中实现拓扑排序、单源最短路径和单源最长路径算法,并提供完整的Java代码示例。 图结构定义 首先,我们定义一个…...
SQLServer按照年龄段进行分组查询数据
1.按照年龄段对数据进行分组, 将人群分为:青年,中年,老年三种类型,人群类型加上其他分组字段如:性别,进行多条件分组,统计各个年龄段多少人 Select case sex when 1 then ‘男’ when 2 then …...

开放式耳机哪个品牌质量比较好?2024高性价比机型推荐!
随着音乐技术的不断发展,开放式耳机已成为音乐发烧友们的另外一种选择。从最初的简单音质,到如今的高清解析,开放式耳机不断进化升级。音质纯净,佩戴舒适,无论是街头漫步还是家中放松时候,都能带给你身临其…...

Blender骨骼创建
骨骼系统 建立 使用Shift A添加骨骼或在添加|骨架中添加一段骨骼 骨骼的三种模式 -物体模式:做动画,摆人物pose时在该模式 -编辑模式:进行骨骼搭建(选择一段骨骼,然后按E挤出一段骨骼并进行调整) -姿…...

DevExpress WPF中文教程:Grid - 如何完成列和编辑器配置(设计时)?
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

高考完的三个月想自学点编程,有没有什么建议
👆点击关注 获取更多编程干货👆 对于刚刚完成高考的学生来说,无论未来是否选择计算机科学作为专业方向,自学编程技能是一项非常有价值的投资,掌握编程知识能够帮助同学们为将来的学习和科研 实践奠定一个基础。 随着…...

运维开发(DevOps):加速软件交付的关键方法
1. 什么是运维开发 运维开发(DevOps)是将软件开发(Development)与信息技术运维(Operations)的流程整合在一起的实践方法。DevOps的目标是通过增强开发和运维团队之间的协作,提高软件产品的发布…...
Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析
Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析 在构建Vue.js项目时,搭建一个稳定且高效的前端环境至关重要。这不仅关乎项目的顺利推进,更直接影响开发者的效率和代码质量。本文将从四个方面、五个方面、六个方面和七个…...

农业领域科技查新点提炼方法附案例!
农业学科是人类通过改造和利用生物有机体(植物、动物、微生物等)及各种自然资源(光、热、水、土壤等)生产出人类需求的农产品的过程,人类在这一过程中所积累的科学原理、技术、工艺和技能,统称为农业科学技术,该领域具有研究范围广、综合性强…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...