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

策略模式(C++)

定义

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换((变化)。该模式使得算法可独立手使用它的客户程序稳定)而变化(扩展,子类化)。
——《设计模式》GoF

使用场景

  • 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
  • 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

结构

在这里插入图片描述

代码示例

//Strategy.h
/****************************************************/
#ifndef STRATEGY_H
#define STRATEGY_H
#include<iostream>
using namespace std;//创建一个定义活动的Strategy的抽象接口
class Strategy
{
public:Strategy() {};virtual ~Strategy() {};virtual int doOperation(int num1, int num2)=0;
};//创建一个实体活动的OperationAdd类
class OperationAdd:Strategy
{
public:OperationAdd() {};virtual ~OperationAdd() {};int doOperation(int num1, int num2) { return num1 + num2; };
};//创建一个实体活动的OperationSubstract类
class OperationSubstract :Strategy
{
public:OperationSubstract() {};virtual ~OperationSubstract() {};int doOperation(int num1, int num2) { return num1 - num2; };
};//创建一个实体活动的OperationMultiply类
class OperationMultiply :Strategy
{
public:OperationMultiply() {};virtual ~OperationMultiply() {};int doOperation(int num1, int num2) { return num1 * num2; };
};//创建一个使用某种策略的Context类
class Context
{
public:Context(Strategy *strate) { mstrate = strate; };virtual ~Context() { delete mstrate; mstrate = NULL; };int executeStrategy(int num1, int num2) { return mstrate->doOperation(num1,num2); };
private:Strategy *mstrate;
};#endif
//test.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Strategy.h"int main()
{Context *c1 = new Context((Strategy*)new OperationAdd());Context *c2 = new Context((Strategy*)new OperationSubstract());Context *c3 = new Context((Strategy*)new OperationMultiply());cout <<"1 + 2 = "<<c1->executeStrategy(1, 2) << endl;cout <<"1 - 2 = "<< c2->executeStrategy(1, 2) << endl;cout <<"1 * 2 = "<< c3->executeStrategy(1, 2) << endl;delete c1;c1 = NULL;delete c2;c2 = NULL;delete c3;c3 = NULL;return 0;
}

运行结果:
在这里插入图片描述

要点总结

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

相关文章:

策略模式(C++)

定义 定义一系列算法&#xff0c;把它们一个个封装起来&#xff0c;并且使它们可互相替换((变化)。该模式使得算法可独立手使用它的客户程序稳定)而变化(扩展&#xff0c;子类化)。 ——《设计模式》GoF 使用场景 在软件构建过程中&#xff0c;某些对象使用的算法可能多种多…...

【每日一题Day290】LC1281整数的各位积和之差 | 模拟

整数的各位积和之差【LC1281】 给你一个整数 n&#xff0c;请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。 思路&#xff1a;简单模拟 循环取余&#xff0c;计算「各位数字之积」与「各位数字之和」&#xff0c;最后求差返回 实现 class Solution {public…...

揭示CTGAN的潜力:利用生成AI进行合成数据

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 我们都知道&#xff0c;GAN在生成非结构化合成数据&#xff08;如图像和文本&#xff09;方面越来越受欢迎。然而&#xff0c;在使用GAN生成合成表格数据方面所做的工作很少。合成数据具有许多好处&#x…...

GitHub中readme.md文件的编辑和使用

GitHub中readme.md文件的编辑和使用 | YuuiChungs BlogGitHub - guodongxiaren/README: README文件语法解读&#xff0c;即Github Flavored Markdown语法介绍...

Python 四舍五入到最接近的十位

本篇文章将讨论使用 Python 的 ceil() 函数将数字四舍五入到最接近的十。 Python 整数到最接近的十 Python 具有三个内置函数 round()、floor() 和 ceil()&#xff0c;可用于对数字进行舍入。 ceil() 函数属于数学模块&#xff0c;用于将浮点数舍入为大于或等于给定数字的最接…...

Unity限制在一个范围内移动

Unity限制在一个范围内移动 这个例子中&#xff0c;我们学习Vector3.ClampMagnitude的用法&#xff0c;限制小球在范围内移动。 在地图上放了一个小球&#xff0c;让他移动&#xff0c;但是不想让他掉下去&#xff0c;限制在一个球星范围内&#xff0c;就好像绳子拴住了一样&…...

dji uav建图导航系列(一)建图

文章目录 1、uav + rplidir雷达1.2、思岚激光雷达1.3、dji uav的launch文件2、cartographer激光建图2.1、启动文件2.2、config修改2.3、建图过程3、融合odom+laser建图1、uav + rplidir雷达 思岚激光雷达frame为base_laser_link, 无人机frame为base_footprint。 文件uav_lid…...

AAAI论文阅读

文章目录 Open-Vocabulary Multi-Label Classifcation via Multi-Modal Knowledge Transfer——知识蒸馏的范畴Med-EASi: Finely Annotated Dataset and Models for Controllable Simplifcation of Medical Texts——医学领域数据集构建“Nothing Abnormal”: Disambiguating M…...

填补5G物联一张网,美格智能快速推进RedCap商用落地

自5G R17版本标准冻结以来&#xff0c;RedCap一直引人注目。2023年更是5G RedCap突破性发展的一年&#xff0c;从首款5G RedCap调制解调器及射频系统——骁龙X35发布&#xff0c;到国内四大运营商发布RedCap技术白皮书&#xff0c;芯片厂商、模组厂商、运营商及终端企业都在积极…...

服务器杂七杂八的知识/常识归纳(不断更新)

一.pID与端口号不一样吗? pID&#xff08;Process ID&#xff0c;进程标识符&#xff09;和端口号是不同的概念。 pID是操作系统中用来唯一标识一个正在运行的进程的数字。每个正在运行的进程都会被分配一个唯一的pID&#xff0c;它可以用来追踪和管理进程。 而端口号是在网…...

掌握Java排序算法:实现主流排序方法与性能对比

一&#xff0c;C语言&#xff0c;主流的排序方法介绍 当谈论主流的排序方法时&#xff0c;通常指的是在实际应用中表现优秀且被广泛采用的排序算法。以下是常见的主流排序方法及其介绍、时间复杂度、空间复杂度和简单的C语言代码实现&#xff1a; 冒泡排序&#xff08;Bubble S…...

jdk17 SpringBoot JPA集成多数据库

switchRegion(切换地区)功能, 客户端可手动切换地区 , 查询不同的数据库, 后台根据地区切换数据库, 请求头添加region的key 配置类 import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; im…...

vue 新学习 06 js的prototype ,export暴露,vue组件,一个重要的内置关系

01 在js中&#xff1a; 原型链 注意&#xff1a;构造函数.prototype实例化对象.__proto__&#xff0c;都是指向函数的原型。 export&#xff1a; -export用于对外输出本模块&#xff08;一个文件可以理解为一个模块&#xff09;变量的接口 -import用于在一个模块中加载另一个…...

冠达管理:“高温超导”不是“室温超导”,5天4板百利电气再次澄清

短短半个月&#xff0c;“室温超导”在惊喜、质疑间回转&#xff0c;但资本市场对“超导概念股”的炒作还在进行&#xff0c;8月7日室温超导概念持续疯涨。同花顺显现&#xff0c;到8月7日收盘&#xff0c;18只超导概念股中&#xff0c;有16只股票飘红。 广东研山私募证券投资&…...

CS 144 Lab Four 收尾 -- 网络交互全流程解析

CS 144 Lab Four 收尾 -- 网络交互全流程解析 引言Tun/Tap简介tcp_ipv4.cc文件配置信息初始化cs144实现的fd家族体系基于自定义fd体系进行数据读写的adapter适配器体系自定义socket体系自定义事件循环EventLoop模板类TCPSpongeSocket详解listen_and_accept方法_tcp_main方法_in…...

Linux面试专题

Linux面试专题 1 Linux中主要有哪几种内核锁?2 Linux 中的用户模式和内核模式是什么含意?3 怎样申请大块内核内存?4用户进程间通信主要哪几种方式?5通过伙伴系统申请内核内存的函数有哪些?6) Linux 虚拟文件系统的关键数据结构有哪些?(至少写出四个)7) 对文件或设备的操作…...

MySQL错误日志(Error Log)详解

错误日志&#xff08;Error Log&#xff09;是 MySQL 中最常用的一种日志&#xff0c;主要记录 MySQL 服务器启动和停止过程中的信息、服务器在运行过程中发生的故障和异常情况等。 作为初学者&#xff0c;要学会利用错误日志来定位问题。下面介绍如何操作查看错误日志。 启动…...

Qt应用开发(基础篇)——LCD数值类 QLCDNumber

一、前言 QLCDNumber类继承于QFrame&#xff0c;QFrame继承于QWidget&#xff0c;是Qt的一个基础小部件。 QLCDNumber用来显示一个带有类似lcd数字的数字&#xff0c;适用于信号灯、跑步机、体温计、时钟、电表、水表、血压计等仪器类产品的数值显示。 QLCDNumber可以显示十进制…...

新版百度、百家号旋转验证码识别

昨天突然发现&#xff0c;百度旋转验证码发生了变化&#xff0c;导致使用老版本验证码训练出来的识别模型效果不佳。所有昨天花了一天时间完成了新版模型的训练。 老版本验证码 新版本验证码 新版的验证码感觉像是AI绘画随机生成的&#xff0c;还有随机阴影出现。 验证码识别…...

PMP考试每日一练(8月8日)

1、项目经理正在领导一个正在努力协作的多元文化团队。项目经理一开始将此视为团队建设的典型震荡阶段&#xff0c;但团队未能成功通过该阶段。结果&#xff0c;项目开始落后于进度。 项目经理在第一次发现这个问题时应该做哪两项工作&#xff1f;&#xff08;选两个&#xff0…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

实现弹窗随键盘上移居中

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

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...