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

策略模式的C++实现示例

核心思想

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在独立的类中,使得它们可以互相替换。策略模式让算法的变化独立于使用它的客户端,从而使得客户端可以根据需要动态切换算法,而不需要修改其代码。策略模式的核心是将算法与使用算法的客户端解耦,使得算法可以独立于客户端变化。

**Context:**持有一个策略对象的引用,负责调用策略的具体实现。
**Strategy:**定义所有支持的算法的公共接口。
**ConcreteStrategy:**实现Strategy接口,提供具体的算法实现。

使用场景

多种算法切换:如排序算法(快速排序、冒泡排序等)或支付方式(信用卡、支付宝等)。
避免条件语句:当代码中有大量条件分支用于选择不同行为时,可以用策略模式替代。
算法复用:当多个类需要共享相同的行为,但行为的具体实现不同时。
动态切换行为:如游戏中的角色在不同状态下使用不同的攻击策略。
测试与调试:策略模式可以方便地替换算法的实现,便于测试和调试。

解决的问题

代码重复问题:
如果多个类使用相同的算法,但算法的实现分散在各处,会导致代码重复。策略模式将算法集中管理,避免重复。

紧耦合问题:
在传统设计中,算法直接嵌入在客户端代码中,导致客户端与算法紧耦合。策略模式通过将算法抽象为接口,解耦了客户端和具体算法。

扩展性问题:
新增算法时,需要修改客户端代码。策略模式允许动态添加新算法,而无需修改现有代码。

条件分支问题:
当代码中有大量条件分支用于选择不同行为时,策略模式可以将其替换为对象的多态调用,使代码更清晰。

优点

**开闭原则:**新增算法无需修改现有代码,只需添加新的策略类。
**解耦:**将算法的实现与使用分离,提高代码的灵活性和可维护性。
**复用性:**策略类可以在不同上下文中复用。
**简化测试:**每个策略类可以独立测试。

缺点

**类数量增加:**每个算法都需要一个单独的类,可能导致类的数量增多。
**客户端需要了解策略:**客户端需要知道有哪些策略,并选择合适的策略。
**性能开销:**策略模式可能引入额外的对象创建和调用开销。

示例代码

如下代码中,Context类(即客户端)是稳定、可以不变的,变化的是策略,而策略是根据运行时的实际情况来选择的。通过继承Strategy类并重写execute()接口实现策略的扩展。

#include <iostream>
#include <memory>// 抽象策略接口
class Strategy {
public:virtual void execute() const = 0;virtual ~Strategy() = default;  // 虚析构函数,确保正确释放资源
};// 具体策略A
class ConcreteStrategyA : public Strategy {
public:void execute() const override {std::cout << "执行策略A" << std::endl;}
};// 具体策略B
class ConcreteStrategyB : public Strategy {
public:void execute() const override {std::cout << "执行策略B" << std::endl;}
};// 上下文类,持有策略对象并调用其方法
class Context {
private:std::unique_ptr<Strategy> strategy;  // 使用智能指针管理策略对象public:// 构造函数,允许传入策略对象Context(std::unique_ptr<Strategy> s) : strategy(std::move(s)) {}// 设置策略void setStrategy(std::unique_ptr<Strategy> s) {strategy = std::move(s);}// 执行策略void executeStrategy() const {if (strategy) {strategy->execute();} else {std::cout << "未设置策略" << std::endl;}}
};int main() {// 创建上下文对象,并初始化为策略AContext context(std::make_unique<ConcreteStrategyA>());context.executeStrategy();  // 输出: 执行策略A// 动态切换到策略Bcontext.setStrategy(std::make_unique<ConcreteStrategyB>());context.executeStrategy();  // 输出: 执行策略Breturn 0;
}

代码说明

​Strategy:抽象策略接口,定义了所有具体策略类必须实现的方法execute()。
​ConcreteStrategyA​ 和 ​ConcreteStrategyB:具体策略类,分别实现了不同的算法或行为。
​Context:上下文类,持有一个策略对象的引用,并提供了设置策略和执行策略的方法。
​智能指针:使用std::unique_ptr管理策略对象的生命周期,避免内存泄漏。

运行结果

执行策略A
执行策略B

总结

通过策略模式,我们可以将算法的实现与使用算法的环境解耦,使得算法可以独立于客户端代码进行扩展和修改。这种设计模式特别适用于需要动态切换算法的场景。

相关文章:

策略模式的C++实现示例

核心思想 策略模式是一种行为型设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每个算法封装在独立的类中&#xff0c;使得它们可以互相替换。策略模式让算法的变化独立于使用它的客户端&#xff0c;从而使得客户端可以根据需要动态切换算法&#xff0c;而不需要修改…...

本地部署pangolin获取谱系,从而达到预测新冠的流行趋势

步骤 1&#xff1a;安装Docker 注&#xff1a;此步骤忽略&#xff0c;可通过Docker官网对于文档进行安装,地址如下 Docker: Accelerated Container Application Developmenthttps://www.docker.com/ 步骤 2&#xff1a;拉取Pangolin镜像 docker pull staphb/pangolin:latest 步…...

【我的 PWN 学习手札】House of Emma

House of Emma 参考文献 第七届“湖湘杯” House _OF _Emma | 设计思路与解析-安全KER - 安全资讯平台 文章 - house of emma 心得体会 - 先知社区 前一篇博客【我的 PWN 学习手札】House of Kiwi-CSDN博客的利用手法有两个关键点&#xff0c;其一是利用__malloc_assert进入…...

4 Redis4 List命令类型讲解

Redis 列表&#xff08;List&#xff09;命令详解 1. Redis 列表&#xff08;List&#xff09;简介 Redis 列表&#xff08;List&#xff09;是一个简单的字符串列表&#xff0c;按照插入顺序排序。它可以用作 栈&#xff08;Stack&#xff09; 和 队列&#xff08;Queue&…...

CentOS 7 安装 Redis6.2.6

获取资源、下载安装 Redis6.2.6 安装Redis6.2.6 上传到服务器或直接下载&#xff08;wget http://download.redis.io/releases/redis-6.2.6.tar.gz&#xff09;、再解压安装 tar -zxvf redis-6.2.6.tar.gz 进入redis解压目录 cd redis-6.2.6先编译 make再执行安装 make PREFI…...

数据库原理4

1.数据库中的数据通常可分为用户数据和系统数据两部分。用户数据是用户使用的数据&#xff1b;系统数据称为数据字典。 2.SQL语言的功能&#xff1a;数据查询&#xff1b;数据操纵&#xff1b;数据定义&#xff1b;数据操作&#xff1b;数据控制 3.对未提交更新的依赖&#x…...

doris: MySQL

Doris JDBC Catalog 支持通过标准 JDBC 接口连接 MySQL 数据库。本文档介绍如何配置 MySQL 数据库连接。 使用须知​ 要连接到 MySQL 数据库&#xff0c;您需要 MySQL 5.7, 8.0 或更高版本 MySQL 数据库的 JDBC 驱动程序&#xff0c;您可以从 Maven 仓库下载最新或指定版本的…...

Django模型数据删除:详解两种方式

Django模型数据删除&#xff1a;详解两种方式 在Django框架中&#xff0c;数据模型&#xff08;Model&#xff09;不仅定义了应用的数据结构&#xff0c;还提供了与数据库交互的接口&#xff0c;包括数据的删除操作。本文将详细介绍两种在Django中删除数据的方式&#xff1a;通…...

C++并发以及多线程的秘密

1.基础概念 并发&#xff08;Concurrency&#xff09; 并发是指在同一时间段内&#xff0c;多个任务看起来像是同时执行的。并发并不一定意味着真正的同时执行&#xff0c;它可以是通过时间片轮转等方式在多个任务之间快速切换&#xff0c;让用户感觉多个任务在同时进行。并发…...

自学微信小程序的第十二天

DAY12 1、腾讯地图SDK是一套为开发者提供多种地理位置服务的工具,可以使开发者在自己的应用中加入地图相关功能,轻松访问腾讯地图服务和数据,更好地实现微信小程序的地图功能。 表49:search()方法的常用选项 选项 类型 说明 keyword string POI搜索关键词,默认周边搜索 l…...

⭐算法OJ⭐跳跃游戏【贪心算法】(C++实现)Jump Game 系列 I,II

既股票买卖系列之后的第二组贪心算法题目&#xff1a;跳跃游戏系列。这一篇介绍的两个问题&#xff0c;其输入均为一个数组&#xff0c;每个元素表示在该位置可以跳跃的最大长度。 55. Jump Game You are given an integer array nums. You are initially positioned at the …...

带你从入门到精通——自然语言处理(五. Transformer中的自注意力机制和输入部分)

建议先阅读我之前的博客&#xff0c;掌握一定的自然语言处理前置知识后再阅读本文&#xff0c;链接如下&#xff1a; 带你从入门到精通——自然语言处理&#xff08;一. 文本的基本预处理方法和张量表示&#xff09;-CSDN博客 带你从入门到精通——自然语言处理&#xff08;二…...

ubuntu挂载固态硬盘

Ubuntu 中挂载位于 /dev/sdc1 的固态硬盘&#xff0c;可以按照以下步骤操作&#xff1a; 步骤 1&#xff1a;确认分区信息 首先&#xff0c;确保设备 /dev/sdc1 存在且已正确分区&#xff1a; sudo fdisk -l /dev/sdc # 查看分区表 lsblk # 确认分区路…...

WPF+WebView 基础

1、基于.NET8&#xff0c;通过NuGet添加Microsoft.Web.WebView2。 2、MainWindow.xaml代码如下。 <Window x:Class"Demo.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/win…...

国内光子AI智能引擎:OptoChat AI在南京江北新区亮相

3月3日&#xff0c;从南京市投资促进局传来振奋人心的消息&#xff0c;南京江北新区的一家高科技企业——南京南智先进光电集成技术研究院有限公司&#xff08;简称“南智光电”&#xff09;&#xff0c;携手南京知满科技等合作伙伴&#xff0c;成功研发出国内首个光子AI智能引…...

vscode离线配置远程服务器

目录 一、前提 二、方法 2.1 查看vscode的commit_id 2.2 下载linux服务器安装包 2.3 安装包上传到远程服务器&#xff0c;并进行文件解压缩 三、常见错误 Failed to set up socket for dynamic port forward to remote port&#xff08;vscode报错解决方法&#xff09;-C…...

【安装】SQL Server 2005 安装及安装包

安装包 SQLEXPR.EXE&#xff1a;SQL Server 服务SQLServer2005_SSMSEE.msi&#xff1a;数据库管理工具&#xff0c;可以创建数据库&#xff0c;执行脚本等。SQLServer2005_SSMSEE_x64.msi&#xff1a;同上。这个是 64 位操作系统。 下载地址 https://www.microsoft.com/zh-c…...

使用Maven搭建Spring Boot框架

文章目录 前言1.环境准备2.创建SpringBoot项目3.配置Maven3.1 pom.xml文件3.2 添加其他依赖 4. 编写代码4.1 启动类4.2 控制器4.3 配置文件 5.运行项目6.打包与部署6.1 打包6.2 运行JAR文件 7.总结 前言 Spring Boot 是一个用于快速构建 Spring 应用程序的框架&#xff0c;它简…...

将docker容器打包为.tar包

1. 创建打包脚本 #!/bin/bash # 设置 -e 使得脚本在遇到错误时停止执行 set -e# 必要的参数 exported_container_name"needed_export_container_name_or_id" # 需要被导出的容器的名称或id image_save_name"my_custom_image_name:v25.03.03" # 镜像需…...

SYSTEM文件夹下的文件

sys文件夹下的.c和.h文件里的函数 最重要的倒数第二个 deley文件夹下的.c和.h文件 Systick工作原理 系统滴答定时器是在内核里的 每来一个时钟信号&#xff0c;计数器减一 F1系列时钟源是HCLK&#xff08;就是AHB总线上的时钟信号&#xff09; Systick控制寄存器 Systick重装…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...