设计模式 策略模式(Strategy Pattern) C++表达

设计模式 策略模式(Strategy Pattern) C++表达

flyfish

策略模式(Strategy Pattern)是一种行为设计模式,它的核心思想是将一系列相关的算法或行为封装到独立的策略类中,并使得这些策略可以相互替换。主要用来定义一系列可互换的算法或行为。它允许在运行时选择和切换这些算法或行为,而不用修改使用它们的代码。

策略模式就像给的代码提供了一组不同的工具,每个工具都可以完成相似的工作(例如不同的送货方式)。可以根据需要随时更换这些工具,而不需要修改太多代码。

举个例子

想象一下,有一家快递公司,提供了不同的送货方式:比如通过快递车、无人机或自行车送货。每种送货方式都有不同的优缺点和适用场景。希望可以根据具体情况选择最合适的送货方式。

如何实现?

  1. 定义策略接口 :首先,定义一个公共接口,比如 DeliveryMethod,里面有一个 deliver 方法,所有具体的送货方式都要实现这个方法。
class DeliveryMethod {
public:virtual void deliver() const = 0; // 定义送货方法virtual ~DeliveryMethod() = default; // 虚析构函数
};
  1. 实现具体策略 :然后,为每种送货方式实现这个接口,比如 TruckDeliveryDroneDeliveryBikeDelivery
class TruckDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by truck." << std::endl;}
};class DroneDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by drone." << std::endl;}
};class BikeDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by bike." << std::endl;}
};
  1. 上下文类 :然后,有一个上下文类 DeliveryContext,它包含一个 DeliveryMethod 的对象,并在需要的时候调用 deliver 方法。这个上下文类可以动态地更换送货方式。
class DeliveryContext {
private:std::shared_ptr<DeliveryMethod> deliveryMethod; // 存储送货方法的指针
public:void setDeliveryMethod(std::shared_ptr<DeliveryMethod> method) {deliveryMethod = method;}void executeDelivery() const {if (deliveryMethod) {deliveryMethod->deliver();}}
};
  1. 使用策略模式 :在 main 函数中,可以创建不同的送货方式,并根据情况切换它们。
int main() {DeliveryContext context;// 设置并执行卡车送货context.setDeliveryMethod(std::make_shared<TruckDelivery>());context.executeDelivery();// 设置并执行无人机送货context.setDeliveryMethod(std::make_shared<DroneDelivery>());context.executeDelivery();// 设置并执行自行车送货context.setDeliveryMethod(std::make_shared<BikeDelivery>());context.executeDelivery();return 0;
}

完整示例:

#include <iostream>
#include <memory>// 策略接口类
class DeliveryMethod {
public:virtual void deliver() const = 0; // 定义送货方法virtual ~DeliveryMethod() = default; // 虚析构函数
};// 具体策略A类 - 卡车送货
class TruckDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by truck." << std::endl;}
};// 具体策略B类 - 无人机送货
class DroneDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by drone." << std::endl;}
};// 具体策略C类 - 自行车送货
class BikeDelivery : public DeliveryMethod {
public:void deliver() const override {std::cout << "Delivering by bike." << std::endl;}
};// 上下文类
class DeliveryContext {
private:std::shared_ptr<DeliveryMethod> deliveryMethod; // 存储送货方法的指针public:// 设置策略方法void setDeliveryMethod(std::shared_ptr<DeliveryMethod> method) {deliveryMethod = method;}// 执行策略方法void executeDelivery() const {if (deliveryMethod) {deliveryMethod->deliver();}}
};int main() {DeliveryContext context; // 创建上下文对象// 设置并执行卡车送货context.setDeliveryMethod(std::make_shared<TruckDelivery>());context.executeDelivery();// 设置并执行无人机送货context.setDeliveryMethod(std::make_shared<DroneDelivery>());context.executeDelivery();// 设置并执行自行车送货context.setDeliveryMethod(std::make_shared<BikeDelivery>());context.executeDelivery();return 0;
}

策略模式还是这样写

  1. 使用 shared_ptr :允许多个上下文对象共享同一个策略对象,节省内存。
  2. 策略工厂和注册机制 :使用 StrategyFactory 类进行策略的注册和创建,支持动态添加新策略,并避免重复创建策略对象。
  3. 简化策略设置 :通过策略名称字符串来设置策略。
#include <iostream>
#include <memory>
#include <unordered_map>
#include <functional>// 策略接口类
class Strategy {
public:virtual ~Strategy() = default; // 虚析构函数,确保派生类对象可以被正确销毁virtual void execute() const = 0; // 纯虚函数,定义了算法的接口
};// 具体策略A类
class ConcreteStrategyA : public Strategy {
public:void execute() const override {std::cout << "Strategy A executed." << std::endl;}
};// 具体策略B类
class ConcreteStrategyB : public Strategy {
public:void execute() const override {std::cout << "Strategy B executed." << std::endl;}
};// 策略工厂类
class StrategyFactory {
public:using CreateStrategyFn = std::function<std::shared_ptr<Strategy>()>;static StrategyFactory& instance() {static StrategyFactory factory;return factory;}void registerStrategy(const std::string& name, CreateStrategyFn createFn) {strategyMap_[name] = createFn;}std::shared_ptr<Strategy> getStrategy(const std::string& name) {auto it = strategyMap_.find(name);if (it != strategyMap_.end()) {return it->second();}return nullptr;}private:std::unordered_map<std::string, CreateStrategyFn> strategyMap_;
};// 上下文类
class Context {
private:std::shared_ptr<Strategy> strategy_; // 存储策略对象的智能指针public:// 设置策略方法void setStrategy(const std::string& strategyName) {strategy_ = StrategyFactory::instance().getStrategy(strategyName);}// 执行策略方法void executeStrategy() const {if (strategy_) {strategy_->execute(); // 调用当前策略的执行方法}}
};int main() {// 注册策略StrategyFactory::instance().registerStrategy("A", []() { return std::make_shared<ConcreteStrategyA>(); });StrategyFactory::instance().registerStrategy("B", []() { return std::make_shared<ConcreteStrategyB>(); });Context context; // 创建上下文对象// 设置并执行策略Acontext.setStrategy("A");context.executeStrategy();// 设置并执行策略Bcontext.setStrategy("B");context.executeStrategy();return 0;
}

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

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

相关文章

线性回归和逻辑回归API

1. 线性回归&#xff08;Linear Regression&#xff09; 主要类 LinearRegression: 这是scikit-learn中用于实现线性回归的类。 用法 from sklearn.linear_model import LinearRegression# 创建模型实例 model LinearRegression()主要参数 fit_intercept: 默认为True。是…

遇到的问题123

1.update:visible更新数据不生效 父组件传递的visible值不是ref定义的响应值&#xff0c;要加v-model修饰符 v-model:visible"chartsConfig.visible"

测试面试宝典(三十五)—— fiddler的工作原理

Fiddler 是一款强大的 Web 调试工具&#xff0c;其工作原理主要基于代理服务器的机制。 首先&#xff0c;当您在计算机上配置 Fiddler 为系统代理时&#xff0c;客户端&#xff08;如浏览器&#xff09;发出的所有 HTTP 和 HTTPS 请求都会被导向 Fiddler。 Fiddler 接收到这些…

springcloud接入seata管理分布式事务

下载安装包 链接: seata 配置seata-server 文件上传Linux解压 压缩包我放在/usr/local/seata中 tar -zxvf seata-server-2.0.0.tar.gz修改配置文件 设置nacos为注册和配置中心 进入文件夹 cd /usr/local/seata/seata/conf修改application.yml文件 ...... ...... cons…

CST软件如何进行参数化扫描?

在用CST进行仿真设计的过程中&#xff0c;经常需要对某一些参数进行参数化设置&#xff0c;并对这些参数进行仿真对比。这一期&#xff0c;我们介绍下如何进行参数化扫描。 还是借用&#xff0c;之前已经对馈电位置、贴片的长和宽都进行了参数设置&#xff0c;如下图所示&…

计算机网络HTTP全讲解,让你透彻掌握HTTP协议(三)http长短连接/代理/网关/缓存/内容协商机制/断点续传

HTTP HTTP的长连接与短连接短链接长链接HTTP代理代理的作用HTTP网关web网关常见的网关类型HTTP缓存HTTP缓存头部字段HTTP缓存工作方式缓存改进方案cdn缓存工作方式浏览器操作对http缓存的影响HTTP内容协商机制客户端驱动服务器驱动请求首部集近似匹配透明协商断点续传和多线程下…

深拷贝——JSON.stringify()序列化和JSON.prase()反序列化

为什么要使用深拷贝&#xff1f; 1、简单理解 JSON.parse() 和 JSON.stringify() 是 JavaScript 中用于处理 JSON 数据的两个内置方法 使用深拷贝的主要原因是为了创建一个对象或数组的完全独立副本&#xff0c;这样对副本的任何更改都不会影响到原始数据。 在 JavaScript …

springboot投票管理系统-计算机毕业设计源码33128

摘 要 本文介绍了基于微信小程序和Spring Boot的投票管理系统的设计与实现。该系统结合了移动互联网技术和后端开发框架&#xff0c;旨在为各类组织或活动提供一个高效、便捷、用户友好的在线投票平台。 系统采用微信小程序作为前端展示与交互界面&#xff0c;用户无需下载安装…

图片等比例缩放方案

图片等比例缩放方案 在Web开发时无可避免的需要将图片进行缩放&#xff0c;缩放时需要保证图片不变形&#xff0c;也就是需要等比例缩放。 设定宽度或高度 引入图片时&#xff0c;仅设置图片的width或者是height就可以使另一边自适应&#xff0c;从而实现等比例缩放。 <…

学校如何筹办一场汉字听写大赛

汉字作为中国最宝贵的文化遗产&#xff0c;在五千年的历史长河里&#xff0c;汉字以其浩瀚广博抒写着华夏历史&#xff0c;以其灵秀展示着炎黄之精神。传承汉字文明是我们的使命和主责任。随着科技的发展&#xff0c;现在人们很少用笔书写汉字&#xff0c;导致汉字听写能力普遍…

unity2D游戏开发16弹弓动画

清理动画器 选中PlayerObject,打开Animator,删除原来的四个状态 右键选择Create State |from New Blend Tree; 冲命名为Walk Tree 双击Walk Tree查看Blend Tree Graph 设置属性为2D Simple Directional,再点击加号选择Add Motion Field 添加四个,如图 点击Base Layer

Python面试整理-常用标准库

Python的标准库包含了大量的模块和包,支持各种编程任务,从文件处理、数据序列化,到网络编程等。这些模块预安装在Python中,无需额外安装就可以使用。以下是一些非常有用且常用的标准库模块: 1. os 用于与操作系统进行交互,包括文件和目录管理操作。 import os # 获取当前…

【数据结构】队列(链表实现 + 力扣 + 详解 + 数组实现循环队列 )

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

VSCode修改插件与缓存路径—究极版

一. 安装 安装的时候选中添加到资源管理器中&#xff0c;以便后续修改注册表。当然咱们自己手动建也是可以的 这样安装有个缺点&#xff0c;会在空白处、文件右键、目录右键创建通过VSCode打开。 但是在空白处打开就很不爽&#xff0c;所以删除注册表即可 计算机\HKEY_CLASS…

【WEB安全】 PHP基础文件知识完整教学中(超详细)

文章目录​​​​​​​ 1.PHP 文件处理 PHP 操作文件 PHP 文件打开/读取/关闭 ​​​​​​​文件的 复制 删除 重名 ​​​​​​​文件的判断 2.PHP获取文件属性 3.PHP目录操作 4.命名空间 PHP 命名空间可以解决以下两类问题&#xff1a; 5.正则表达式 正则表达…

python编程,设计一个详细的软件 与SADS 相似

软件功能模块&#xff1a; 用户界面模块&#xff08;UI Module&#xff09; 项目管理界面模型构建界面分析和设计界面结果展示和报告生成界面 数据库模块&#xff08;Database Module&#xff09; 材料数据库结构组件数据库设计标准和规范数据库用户项目数据存储 模型构建模块&…

JAVA ORM(对象关系映射)

目录 一、常见的Java ORM框架 1. Hibernate 2. Java Persistence API (JPA) 3. MyBatis 4. Spring Data JPA 二、ORM的优点 1、简化数据库操作 2、跨数据库支持 3、维护性和可读性 三、ORM的缺点 在Java中&#xff0c;ORM&#xff08;对象关系映射&#xff09;是一种…

机器学习 | 评估原理——准确率、精确率、召回率、F1值

Hi&#xff0c;大家好&#xff0c;我是半亩花海。接着上次的模型评估与交叉验证继续更新《白话机器学习的数学》这本书的学习笔记&#xff0c;在此分享准确率、精确率、召回率、F1值相关评估原理。本章的基于前几节已建立的模型进行评估知识的学习&#xff0c;欢迎大家交流学习…

User-Agent(UA)注入

在CTF&#xff08;Capture The Flag&#xff09;竞赛中&#xff0c;User-Agent&#xff08;UA&#xff09;注入是一种利用Web应用程序安全漏洞的攻击方式&#xff0c;特别是在应用程序基于User-Agent字符串来执行某些逻辑或数据库查询时。User-Agent注入通常涉及到在HTTP请求头…

一篇文章掌握Python爬虫的80%

转载&#xff1a;一篇文章掌握Python爬虫的80% Python爬虫 Python 爬虫技术在数据采集和信息获取中有着广泛的应用。本文将带你掌握Python爬虫的核心知识&#xff0c;帮助你迅速成为一名爬虫高手。以下内容将涵盖爬虫的基本概念、常用库、核心技术和实战案例。 一、Python 爬虫…