策略模式-C++实现

策略模式(Strategy)是一种行为型设计模式,它允许你在运行时选择算法的行为。

策略模式有三个组件:

  • 策略接口:定义了策略类必须实现的方法,它通常是以接口或者抽象类的方式存在
  • 具体策略类:实现了策略接口,提供各种算法。
  • 上下文类:将策略接口作为一个成员变量,运行时通过设置不同的策略类切换不同的算法

举例:
现在我们有一笔金额,要按照不同国家的汇率进行计算,我们可以这样实现:

// 各国汇率
enum Rate
{CN_Rate,	// 中国汇率FR_Rate,	// 英国汇率US_Rate		// 没过汇率
};// 运行
class CalculateRate
{
public:CalculateRate(){}~CalculateRate(){}void SetRate(Rate _rate){rate_ = _rate;}double Calculate(const double& _data){if (rate_ == CN_Rate){// TODO 按照中国汇率进行计算std::cout << "中国汇率" << std::endl;}else if (rate_ == FR_Rate){// TODO 按照法国汇率进行计算std::cout << "法国汇率" << std::endl;}else if (rate_ == US_Rate){// TODO 按照美国汇率进行计算std::cout << "美国汇率" << std::endl;}return 0.0;}private:Rate rate_;
};

我们定义了一个枚举,里面是各个国家的类型,当我们要按照美国的汇率进行计算时,我们可以通过SetRate方法设置国家类型,再调用Calculate方法进行计算,在这个方法里我们会判断当前是哪个国家,执行对应的算法。

其实这个例子已经实现了我们现在的需求,但是项目开发过程中需求是不断的变化。比如现在我们要加一个日本的汇率,我们应该在枚举里添加一个日本,在Calculate方法里继续else if执行日本汇率对应的算法。

这样其实违背了项目开发原则中的开放封闭原则。

所谓开放封闭原则就是对扩展开放、对修改封闭,换句话说我们应该通过添加新的代码来实现需求,而不是修改原有的代码。

现在我们用策略模式来完成这个需求,按照上述策略模式的三个组件来编写代码:策略接口、具体的策略类、上下文类

// 定义策略接口
class Strategy
{
public:virtual ~Strategy(){}virtual double CalculateRate(const double& _data) = 0;
};// 根据中国汇率计算的策略类
class CNRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double& _data) override{// TODO 按照中国汇率进行计算std::cout << "中国汇率" << std::endl;return 0.0;}
};// 按照法国汇率计算的策略类
class FRRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double& _data) override{// TODO 按照法国汇率进行计算std::cout << "法国汇率" << std::endl;return 0.0;}
};// 按照美国汇率计算的策略类
class USRateStrategy: public Strategy
{
public:virtual double CalculateRate(const double& _data) override{// TODO 按照美国汇率进行计算std::cout << "美国汇率" << std::endl;return 0.0;}
};// 上下文类
class Context
{
public:Context(){}void SetRate(std::shared_ptr<Strategy> _strategy){strategy_ = _strategy;}void Calculate(const double& _value){if(strategy_)strategy_->CalculateRate(_value);}private:std::shared_ptr<Strategy> strategy_;
};

我们通过Context类里的SetRate方法设置具体的策略类,通过Calculate方法执行算法。

void TestStrategy()		
{Context context;context.SetRate(std::make_shared<CNRateStrategy>());context.Calculate(10.0);context.SetRate(std::make_shared<FRRateStrategy>());context.Calculate(10.0);context.SetRate(std::make_shared<USRateStrategy>());context.Calculate(10.0);
}int main()
{// 策略模式用法TestStrategy();system("pause");return 0;
}

现在我们要添加一个日本的汇率,我们就可以仿照美国、中国、法国的策略类的写法写一个日本的策略类,在运行的时候设置日本的策略类,这样它就会执行日本的算法。

我们可以发现使用策略模式就不会违背开放封闭原则,因为我们是添加代码而不是修改原有代码。

可能会有人说第一种写法不是也是添加代码吗,我们这里说的“添加”是在二进制的角度,所谓的添加是指添加之后编译添加后的代码,而不是把原有代码重新编译一遍。

总结:

  • Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换
  • Stratergy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
  • 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot+Redis+Lua

Lua脚本 Lua脚本在Redis中执行&#xff0c;避免了多次的客户端与服务器之间的通信。这可以减少网络开销&#xff0c;提高性能&#xff0c;特别是在需要执行多个Redis命令以完成一个操作时。原子性&#xff1a;Redis保证Lua脚本的原子性执行&#xff0c;无需担心竞态条件或并发…

抖音短视频账号矩阵系统、短视频矩阵源码+无人直播源码开发可打包

抖音短视频账号矩阵系统、短视频矩阵源码无人直播源码开发可打包 矩阵系统源码主要有三种框架&#xff1a;Spring、Struts和Hibernate。Spring框架是一个全栈式的Java应用程序开发框架&#xff0c;提供了IOC容器、AOP、事务管理等功能。Struts框架是一个MVC架构的Web应用程序框…

selenium报错:没有打开网页或selenium.common.exceptions.NoSuchDriverException

文章目录 问题解决方法 问题 当selenium的环境配置没有问题&#xff0c;但在使用selenium访问浏览器时并没有打开网页&#xff0c;或者出现selenium.common.exceptions.NoSuchDriverException报错信息&#xff08;如下图所示&#xff09;。 以上问题可能的原因是没有配置chrom…

第三天课程 RabbitMQ

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&am…

[云原生案例2.3 ] Kubernetes的部署安装 【多master集群架构高可用 ---- (二进制安装部署)】

文章目录 1. Kubernetes多Master集群高可用方案1.1 多节点Master高可用的实现过程1.2 实现高可用方法 2. 新Master节点的部署2.1 前置准备2.2 系统初始化操作2.2.1 关闭防火墙、selinux和swap分区2.2.2 修改主机名&#xff0c;添加域名映射2.2.3 修改内核参数2.2.4 时间同步 2.…

批量重命名软件推荐 A Better Finder Rename 12最新 for mac

A Better Finder Rename的大量重命名选项被组织成15个直观的类别&#xff0c;涵盖了一个伟大的文件重命名器所期望的所有文本&#xff0c;字符&#xff0c;位置&#xff0c;转换和截断功能。 除此之外&#xff0c;A Better Finder Rename提供了更多高级功能&#xff0c;可以满…

ATFX汇市:10月美国名义CPI年率大降,美元指数创近三月新低

ATFX汇市&#xff1a;据美国劳工部劳动统计局数据&#xff0c;美国10月未季调CPI年率最新值3.2%&#xff0c;低于前值3.7%&#xff0c;低于预期值3.3%&#xff1b;10月未季调核心CPI年率最新值4%&#xff0c;低于前置和预期值的4.1%。名义CPI与核心CPI双双下降&#xff0c;透露…

计算机网络的发展及应用

计算机网络是计算机技术和通信技术高度发展并相互结合的产物。一方面&#xff0c;通信系统为计算机之间的数据传送提供最重要的支持&#xff1b;另一方面&#xff0c;由于计算机技术渗透到了通信领域&#xff0c;极大地提高了通信网络的性能。计算机网络的诞生和发展&#xff0…

C++什么时候使用指针(函数传参时)

在C中&#xff0c;使用指针作为函数参数可以在以下几种情况下提高效率&#xff1a; 需要修改函数外部的变量&#xff1a;当函数需要修改传递给它的变量的值时&#xff0c;使用指针比传值更高效。因为通过指针传递变量的地址&#xff0c;函数可以直接修改变量的值&#xff0c;而…

音频——解析 PCM 数据

文章目录 生成 PCM 数据16bit16bit mono16bit stereo16bit 4 channel16bit 8 channel24bit解析 PCM 数据多通道相同频率解析多通道不同频率解析程序源码生成 PCM 源码解析 PCM 源码生成 PCM 数据 对于多通道的 PCM 数据,其数据格式如下 ch0_data0 ch1_data0 ch2_data0 ch3_d…

10 小时 RTX 4090 兑换券免费送!用户调研招募中

感谢各位读者长久以来对「HyperAI超神经」的支持与关注&#xff0c;为了进一步提升公众号的品质&#xff0c;为读者提供高质量内容&#xff0c;我们计划通过问卷调研的形式收集读者的感受与建议&#xff0c;从而有针对性地对「HyperAI超神经」的内容风格、呈现形式等方面进行调…

目标检测—Yolo系列(YOLOv1/2/v3/4/5/x/6/7/8)

目标检测概述 什么是目标检测&#xff1f; 滑动窗口&#xff08;Sliding Window&#xff09; 滑动窗口的效率问题和改进 滑动窗口的效率问题&#xff1a;计算成本很大 改进思路 1&#xff1a;使用启发式算法替换暴力遍历 例如 R-CNN&#xff0c;Fast R-CNN 中使用 Selectiv…

第十六章 文件服务

第十六章 文件服务 1 FTP Server 简介 解释 文件传输协议 是 TCP/IP协议组中的协议之一logo 作用 提供文件共享服务互联网上多的媒体资源和软件资源&#xff0c;绝大部分都是通过FTP服务器传递软件包 vsftpd基础 控制端口 command 21/tcp数据端口 data 20/tcpFTP Se…

Qt数据库之QSqlQueryModel

创建数据模型&#xff1a; QSqlQueryModel *qryModel; //数据模型 qryModelnew QSqlQueryModel(this);qryModel->setQuery("SELECT empNo, Name, Gender, Height, Birthday, Mobile, Province, City, Department, "" Education, Salary FROM employee ORDE…

在 Electron上安装better-sqlite3出错

错误问题 一直卡npm install --global windows-build-tools --vs2015 这一步 解决 安装&#xff1a;pnpm install better-sqlite3 --save安装命令 pnpm i -D electron-rebuild 手动运行&#xff1a;node_modules/.bin/electron-rebuild -f -w better-sqlite3 我直接在packa…

Python武器库开发-flask篇之flask框架的安装(二十一)

Flask介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架&#xff0c;对于Werkzeug本质是Socket服务端&#xff0c;其用于接收http请求并对请求进行预处理&#xff0c;然后触发Flask框架&#xff0c;开发人员基于Flask框架提供的功能对请求进…

Stable Diffusion (version x.x) 文生图模型实践指南

前言&#xff1a;本篇博客记录使用Stable Diffusion模型进行推断时借鉴的相关资料和操作流程。 相关博客&#xff1a; 超详细&#xff01;DALL E 文生图模型实践指南 DALLE 2 文生图模型实践指南 目录 1. 环境搭建和预训练模型准备环境搭建预训练模型下载 2. 代码 1. 环境搭建…

redis基线检查

1、禁止使用 root 用户启动 | 访问控制 描述: 使用root权限来运行网络服务存在较大的风险。Nginx和Apache都有独立的work用户,而Redis没有。例如,Redis的Crackit漏洞就是利用root用户权限替换或增加authorize_keys,从而获取root登录权限。 加固建议: 使用root切换到re…

Docker - DockerFile

Docker - DockerFile DockerFile 描述 dockerfile 是用来构建docker镜像的文件&#xff01;命令参数脚本&#xff01; 构建步骤&#xff1a; 编写一个dockerfile 文件docker build 构建成为一个镜像docker run 运行脚本docker push 发布镜像&#xff08;dockerhub&#xff0…

Kyligence 入选 Gartner® 2023 客户之声报告,高分获评“卓越表现者”

近日&#xff0c;Gartner 发布了最新的《2023 分析和商业智能平台“客户之声”报告》(Voice of the Customer for Analytics and Business Intelligence Platforms, 2023, October 2023)。跬智信息&#xff08;Kyligence&#xff09;成功入选该报告&#xff0c;并凭借 4.7 分&a…