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

工厂方法模式(大话设计模式)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;
}

对比简单工厂模式

简单工厂模式例子

  1. 给四种运算新建了四个具体工厂类
  2. 将简单工厂类模式中的工厂创建逻辑判断,移到了客户端代码中

工厂方法模式这样做的目的就是:对创建工厂类的修改关闭,对具体工厂类的扩展开放。

思维思路:

  1. 简单工厂类中的创建工厂类中直接与具体的运算符号产生了依赖,不易于扩展(后期增加运算符,得直接修改工厂类)。
  2. 为了降低耦合,根据依赖倒置的原则(细节依赖抽象),将创建工厂类的分支判断直接改成对应的具体工厂类。

相关文章:

工厂方法模式(大话设计模式)C/C++版本

工厂方法模式 C 参考&#xff1a;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真香

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

性能测试3【搬代码】

1.Linux服务器性能分析命令及详解 2.GarafanainfluxDB监控jmeter数据 3.GarafanaPrometheus监控服务器和数据库性能 4.性能瓶颈分析以及性能调优方案详解 一、无界面压测时&#xff0c; top load average:平均负载 htop 二、Garafana监控平台 传统项目&#xff1a;centosphpm…...

<tesseract><opencv><Python>基于python和opencv,使用ocr识别图片中的文本并进行替换

前言 本文是在python中,利用opencv处理图片,利用tesseractOCR来识别图片中的文本并进行替换的一种实现方法。 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、opencv、tesseractOCR 代码介绍 本文程序功能实现,主要依赖于tesseractOCR这个库,…...

海南云亿商务咨询有限公司解锁抖音电商新纪元

在当今数字化浪潮中&#xff0c;抖音电商以其独特的魅力和强大的用户基础&#xff0c;迅速成为企业营销的新宠。海南云亿商务咨询有限公司&#xff0c;作为专注于抖音电商服务的领先企业&#xff0c;凭借专业的团队和丰富的经验&#xff0c;为众多企业提供了高效、精准的电商服…...

arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例)

arm64架构 统信UOS搭建PXE无盘启动Linux系统&#xff08;麒麟桌面为例&#xff09; 搞了好久搞得头疼哎 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.创建语音通知模板&#xff0c;审核通过4.调用API接口---SingleCallByTts5.调试API接口---SingleCallByTts 二、代码实现1.导入依赖 com.aliyun:aliyun-java-sdk-dyvmsapi:3.0.22.创建工具类&#xff0c;用于发送语音通知…...

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网址的相关方法

目录 第一章 场景 第二章 总结 第一章 场景 最近实现需求时遇到这么一种情况&#xff1a; 本地url —— 线上url —— 需求&#xff1a;需要将token清除掉 注意事项&#xff1a;token不是#/后面的参数&#xff0c;说明并不是我们前端返回的&#xff0c;vue路由的方法使用不…...

java-final 关键字

## Java中的final关键字 ### 1. final关键字的基本概念 final是Java中一个非常重要的关键字&#xff0c;用于声明常量、阻止继承和重写&#xff0c;确保类、方法和变量的不可变性。具体来说&#xff0c;final关键字可以用来修饰类、方法和变量&#xff08;包括成员变量和局部…...

ARM32开发--IIC软实现

知不足而奋进 望远山而前行 目录 文章目录 前言 开发流程 GD32F4软件I2C初始化 GD32F4软件I2C引脚功能 写操作 读操作 总结 前言 在嵌入式系统开发中&#xff0c;软件实现的I2C通信协议扮演着至关重要的角色。本文将深入探讨如何在GD32F4系列微控制器上实现软件I2C功能…...

在有向无环图(DAG)中实现拓扑排序与最短路径和最长路径算法

有向无环图&#xff08;DAG&#xff09;是一类非常重要的图结构&#xff0c;广泛应用于任务调度、数据依赖分析等领域。本文将介绍如何在DAG中实现拓扑排序、单源最短路径和单源最长路径算法&#xff0c;并提供完整的Java代码示例。 图结构定义 首先&#xff0c;我们定义一个…...

SQLServer按照年龄段进行分组查询数据

1.按照年龄段对数据进行分组&#xff0c; 将人群分为&#xff1a;青年&#xff0c;中年&#xff0c;老年三种类型&#xff0c;人群类型加上其他分组字段如&#xff1a;性别&#xff0c;进行多条件分组,统计各个年龄段多少人 Select case sex when 1 then ‘男’ when 2 then …...

开放式耳机哪个品牌质量比较好?2024高性价比机型推荐!

随着音乐技术的不断发展&#xff0c;开放式耳机已成为音乐发烧友们的另外一种选择。从最初的简单音质&#xff0c;到如今的高清解析&#xff0c;开放式耳机不断进化升级。音质纯净&#xff0c;佩戴舒适&#xff0c;无论是街头漫步还是家中放松时候&#xff0c;都能带给你身临其…...

Blender骨骼创建

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

DevExpress WPF中文教程:Grid - 如何完成列和编辑器配置(设计时)?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

高考完的三个月想自学点编程,有没有什么建议

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

运维开发(DevOps):加速软件交付的关键方法

1. 什么是运维开发 运维开发&#xff08;DevOps&#xff09;是将软件开发&#xff08;Development&#xff09;与信息技术运维&#xff08;Operations&#xff09;的流程整合在一起的实践方法。DevOps的目标是通过增强开发和运维团队之间的协作&#xff0c;提高软件产品的发布…...

Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析

Vue前端环境搭建&#xff1a;从四个方面、五个方面、六个方面和七个方面深度解析 在构建Vue.js项目时&#xff0c;搭建一个稳定且高效的前端环境至关重要。这不仅关乎项目的顺利推进&#xff0c;更直接影响开发者的效率和代码质量。本文将从四个方面、五个方面、六个方面和七个…...

农业领域科技查新点提炼方法附案例!

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

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...