C++设计模式 #3策略模式(Strategy Method)
动机
- 在软件构建过程中,某些对象使用的的算法可能多种多样,经常改变。如果将这些算法都写在类中,会使得类变得异常复杂;而且有时候支持不频繁使用的算法也是性能负担。
如何在运行时根据需求透明地更改对象的算法?将算法和对象本身解耦,从而避免上述问题?
举个栗子
我们假设现在有一个需求,需要对不同的颜色做不同的策略(算法)。
enum Color {RED,BLUE
};class strategy {
private:Color color;
public:void strategy_func() {if (color == RED) {//do something}else if (color == BLUE) {// do something else}}
};
以上是比较经典的做法,使用一个枚举类型来指定当前的颜色,对不同的颜色做不同的处理。
那么,如果需求改变了,新增了一个粉色,那么代码需要做如下更改
enum Color {RED,BLUE,PINK //变化
};class strategy {
private:Color color;
public:void strategy_func() {if (color == RED) {//do something}else if (color == BLUE) {// do something else}else if (color == PINK) { //变化// do sth with pink}}
};
这样的作法虽然可行,但是违背了开放封闭(OCP)的设计原则。也就是类模块是可扩展的,但是不要修改。
设计模式的原则详见:)C++设计模式#1-CSDN博客
策略模式做法
我们修改我们的类如下
class strategy {
public:virtual void func() = 0;virtual ~strategy(){}
};class REDstrategy :public strategy {virtual void func() {// do something}
};class BLUEstrategy :public strategy {virtual void func() {// do something}
};class PINKstrategy :public strategy {virtual void func() {// do something}
};class solution {
private:strategy* pointer;
public:void solute() {// ...// 确认颜色// 或者在构造函数中确认颜色// 即pointer指针指向哪个子类pointer->func();//...}
};
我们将对应不同颜色的方法,修改成从同一个基类中继承出来的子类。
在最后的solution中,使用基类的指针,使用多态思想来确认颜色和对应的处理方法,并调用。
这样在新的需求到达的时候,我们只需要新增一个继承出的子类并实现对应的算法即可。其他方法都不需要修改。(如何在solution过程中确定是否是新增的颜色,可以在构造函数中使用工厂设计模式)
模式定义
定义一系列算法,将它们一个个封装起来,并且使它们可以相互替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。——《设计模式》
结合上面的代码理解模式的定义,互相替换也就是也就是PINKstrategy类的添加。独立于客户程序也就是solution类,保证了solution类的稳定,变化指多态地使用不同颜色子类的func()。
红色圈中的是稳定的部分,也就是对应以上的strategy和solution类。蓝色圈中的是变化的部分,也就是以上的对应各个颜色的子类。
总结
- 策略模式及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需求在各个算法之间进行切换。
运行时
多态的指针的子类方法就实现了运行时确定的需求。
- 策略模式给很多if-else语句结构提供了另外一种解决方案。
- 在负载方面。如果strategy对象没有实例变量,那么上下文可以共享同一个strategy对象,从而节省对象开销。
并且,大段的if-else代码不用加载到内存中
相关文章:

C++设计模式 #3策略模式(Strategy Method)
动机 在软件构建过程中,某些对象使用的的算法可能多种多样,经常改变。如果将这些算法都写在类中,会使得类变得异常复杂;而且有时候支持不频繁使用的算法也是性能负担。 如何在运行时根据需求透明地更改对象的算法?将…...
金融知识——OMS、EMS和PMS分别是什么意思
金融知识——OMS、EMS和PMS分别是什么意思 OMSEMSPMS OMS OMS(Order Management System)是为了管理头寸,以多种方式创建订单,并进行订单屈从检验以使得用户在订单创建时收到一些约束。在交易管理方面,OMS提供交易组合…...

Docker——微服务的部署
Docker——微服务的部署 文章目录 Docker——微服务的部署初识DockerDocker与虚拟机Docker架构安装DockerCentOS安装Docker卸载(可选)安装docker启动docker配置镜像加速 Docker的基本操作Docker的基本操作——镜像Docker基本操作——容器Docker基本操作—…...

AI时代架构设计新模式
云原生架构原则 云原生架构本身作为一种架构,也有若干架构原则作为应用架构的核心架构控制面,通过遵从这些架构原则可以让技术主管和架构师在做技术选择时不会出现大的偏差。 服务化原则 当代码规模超出小团队的合作范围时,就有必要进行服务…...
速盾网络:高防IP的好处
随着互联网的快速发展,网络安全问题日益突出,越来越多的企业和个人开始关注网络安全防护。其中,高防IP作为一种高效的防御手段,越来越受到用户的青睐。本文将介绍速盾网络高防IP的好处,帮助您了解其优势和应用场景。一…...

创建Maven Web工程
目录下也会有对应的生命周期。其中常用的是:clean、compile、package、install。 比如这里install ,如果其他项目需要将这里的模块作为依赖使用,那就可以 install 。安装到本地仓库的位置: Java的Web工程,所以我们要选…...

【PHP入门】2.2 流程控制
-流程控制- 流程控制:代码执行的方向 2.2.1控制分类 顺序结构:代码从上往下,顺序执行。(代码执行的最基本结构) 分支结构:给定一个条件,同时有多种可执行代码(块)&am…...

springCould中的zookeeper-从小白开始【3】
目录 1.启动zookeeper❤️❤️❤️ 2.创建8004模块 ❤️❤️❤️ 3.临时节点还是永久节点❤️❤️❤️ 4.创建zk80消费模块❤️❤️❤️ 1.启动zookeeper❤️❤️❤️ 进入自己zookeeper的bin目录下 分别使用命令: ./zkServer.sh start 和 ./zkCli.sh -serve…...

Node.js-模块化(二)
1. 模块化的基本概念 1.1 什么是模块化 模块化是指解决一个复杂问题时,自顶向下逐层将系统拆分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。 1.2 编程领域中的模块化 编程领域中的模块化,就是遵守固定的规则&…...
MAC 安装nginx
使用Homebrew方式进行安装 步骤: 1、更新 Homebrew brew update 2、下载并安装 Nginx brew install nginx 3、查看 nginx 配置信息 brew info nginx zhanghuaBreeze ~ % brew info nginx // 版本信息 > nginx: stable 1.25.1 (bottled), HEAD HTTP(S) se…...

开源 AI 新秀崛起:Bittensor 更像是真正的“OpenAI”
强大的人工智能正在飞速发展,而完全由 OpenAI、Midjourney、Google(Bard)这样的少数公司控制 AI 不免让人感到担忧。在这样的背景下,试图用创新性解决方案处理人工智能中心化问题、权力集中于少数公司的 Bittensor,可谓…...

设计模式:循序渐进走入工厂模式
文章目录 前言一、引入二、简单工厂模式1.实现2.优缺点3.扩展 三、工厂方法模式1.实现2.优缺点 四、抽象工厂模式1.实现2.优缺点3.使用场景 五、模式扩展六、JDK源码解析总结 前言 软件设计模式之工厂模式。 一、引入 需求:设计一个咖啡店点餐系统。 设计一个咖啡类…...

如何将图片(matlab、python)无损放入word论文
许多论文对插图有要求,直接插入png、jpg一般是不行的,这是一篇顶刊文章(pdf)的插图,放大2400%后依旧清晰,搜罗了网上的方法,总结了一下如何将图片无损放入论文中。 这里主要讨论的是数据生成的图…...

在Next.js和React中搭建Cesium项目
在Next.js和React中搭建Cesium项目,需要确保Cesium能够与服务端渲染(SSR)兼容,因为Next.js默认是SSR的。Cesium是一个基于WebGL的地理信息可视化库,通常用于在网页中展示三维地球或地图。下面是一个基本的步骤,用于在Next.js项目中…...

docker学习(十、搭建redis集群,三主三从)
文章目录 一、docker创建6个redis容器创建6个redis容器回顾各个属性含义 二、划分主从,3主3从划分主从查看状态查看节点信息 docker搭建Redis集群相关知识: docker学习(九、分布式存储亿级数据知识) docker学习(十、搭…...

ES排错命令
GET _cat/indices?v&healthred GET _cat/indices?v&healthyellow GET _cat/indices?v&healthgreen确定哪些索引有问题,多少索引有问题。_cat API 可以通过返回结果告诉我们这一点 查看有问题的分片以及原因。 这与索引列表有关,但是索引…...

爬虫实战案例 -- 爬取豆瓣读书网页内容
进入网站检查信息 , 确定请求方式以及相关数据 找到爬取目标位置 开始敲代码 # 链接网站 def url_link(url):res requests.get(url,headers headers)response res.textparse_data(response)# 爬取信息 def parse_data(data):msg <li\sclass"media\sclearfix…...

某电子文档安全管理系统 SQL注入漏洞复现
漏洞介绍 亿赛通电子文档安全管理系统 (简称: CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护…...
ant-design-vue Message 用法以及内容为 html片段情况
全局配置: // main.ts// 进行全局配置 message.config({top: 0.7rem,//高度位置duration: 2,//提示持续时间maxCount: 1,//最大页面同时展示几条 });项目中最常用的用法: 1. 字符串 message.success("导入成功");2. html片段 message.error…...

2024 Move 开发者大会火热报名中!1 月 13 至 14 日上海见
2024 Move 开发者大会将于 1 月 13 日至 1 月 14 日在上海举办。本届 Move 开发者大会以 “Move 生态关键的一年” 为主题,由 MoveFuns 、OpenBuild 和 MoveBit 主办,Rooch、AptosGlobal、alcove、zkMove、云赛空间和 TinTinLand 协办,并得到…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...

在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...