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代码不用加载到内存中

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重生奇迹mu翅膀合成

在重生奇迹mu中,合成翅膀需要准备好翅膀碎片、宝石、羽毛、强化精华等材料,而其中不同翅膀合成要求的材料和数量略有不同。以下是一般合成翅膀的步骤: 1.首先,需要在背包中准备好所有的合成材料。如果缺少任何一种材料&#xff0…

Postman —— HTTP请求基础组成部分

一般来说,所有的HTTP Request都有最基础的4个部分组成:URL、 Method、 Headers和body。 (1)Method 要选择Request的Method是很简单的,Postman支持所有的请求方式。 (2)URL 要组装一条Request&…

【C++进阶02】多态

一、多态的概念及定义 1.1 多态的概念 多态简单来说就是多种形态 同一个行为,不同对象去完成时 会产生出不同的状态 多态分为静态多态和动态多态 静态多态指的是编译时 在程序编译期间确定了程序的行为 比如:函数重载 动态多态指的是运行时 在程序运行…

Java整合APNS推送消息-IOS-APP(基于.p12推送证书)

推送整体流程 1.在开发者中心申请对应的证书(我用的是.p12文件) 2.苹果手机用户注册到APNS,APNS将注册的token返回给APP(服务端接收使用)。 3.后台服务连接APNS,获取连接对象 4.后台服务构建消息载体 5.后台…

Windows漏洞利用开发——利用SEH绕过GS保护

实验6 Windows漏洞利用开发 6.1实验名称 Windows漏洞利用开发 6.2实验目的 学习windows漏洞利用开发,使用kali linux相关工具对windows内目标程序进行漏洞利用 6.3实验步骤及内容 第二阶段:利用SEH绕过GS保护 了解GS编译选项,SHE异常处…

最小二乘法简介

最小二乘法简介 1、背景描述2、最小二乘法2.1、最小二乘准则2.2、最小二乘法 3、最小二乘法与线性回归3.1、最小二乘法与线性回归3.2、最小二乘法与最大似然估计 4、正态分布(高斯分布) 1、背景描述 在工程应用中,我们通常会用一组观测数据去…

数据大模型与低代码开发:赋能技术创新的黄金组合

在当今技术领域,数据大模型和低代码开发已经成为两个重要的趋势。数据大模型借助庞大的数据集和强大的计算能力,助力我们从海量数据中挖掘出有价值的洞见和预测能力。与此同时,低代码开发通过简化开发流程和降低编码需求,使得更多…

Flink实时电商数仓(五)

FlinkSQL的join Regular join普通join,两条流的数据都时存放在内存的状态中,如果两条流数据都很大,对内存压力很大。Interval Join: 适合两条流到达时间有先后关系的;一条流的存活时间短,一条流的存活时间长。Lookup …

【机器学习】贝叶斯决策论

参考课程视频:https://www.icourse163.org/course/NEU-1462101162?tid1471214452 1 概述 1.1 相关概念与变量描述 1.2 贝叶斯定理 2 分类准则 2.1 最大后验概率分类准则 2.2 最小错误概率分类准则 ) 2.3 最小风险分类准则 2.4 栗子 —— 根据身高预测性别

基于AWD攻防对Web漏洞的研究

写在前面 Copyright © [2023] [Myon⁶]. All rights reserved. 基于awd攻防环境和xshell远程连接,配合kali linux渗透系统、蚁剑、D盾、河马、Seay代码审计系统等,演示现实中网站可能存在的漏洞,对网站进行漏洞扫描,渗透测…

网络爬虫之Ajax动态数据采集

动态数据采集 规则 有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面教据,但是使用 requests 得到的结果并没有,这是因为requests 获取的都是原始的 HTML 文档…

nodejs+vue+ElementUi家政服务系统c90g5

项目中登录模块用到token家政服务平台有管理员,雇主,雇员三个角色。管理员功能有个人中心,雇主管理,雇员管理,资料认证管理,项目类型管理,服务项目管理,需求信息管理,服务…

探索微软Edge:使用方法和心得分享

学习目标: 了解微软Edge的基本功能和使用方法。掌握在微软Edge上进行浏览、搜索和书签管理的技巧。学习如何使用微软Edge进行隐私和安全管理。探索微软Edge的扩展和其他高级功能。 学习内容: 微软Edge的简介:了解微软Edge的起源、特点和与其…

NiNNet

目录 一、网络介绍 1、全连接层存在的问题 2、NiN的解决方案(NiN块) 3、NiN架构 4、总结 二、代码实现 1、定义NiN卷积块 2、NiN模型 3、训练模型 一、网络介绍 NiN(Network in Network)是一种用于图像识别任务的卷积神经网络模型。它由谷歌研究…

设计模式除盲

目录 1.设计模式概述1.1 软件设计模式的产生背景1.2.软件设计模式的概念1.3 学习设计模式的必要性1.4 设计模式分类 2.UML图2.1 类图概述2.2 类图的作用2.3 类图表示法2.3.1 类的表示方式2.3.2 类与类之间关系的表示方式2.3.2.1 关联关系2.3.2.2 聚合关系2.3.2.3 组合关系2.3.2…

驱动开发-1

一、驱动课程大纲 内核模块字符设备驱动中断 二、ARM裸机代码和驱动有什么区别? 1、共同点: 都能够操作硬件 2、不同点: 1)裸机就是用C语言给对应的寄存器里面写值,驱动是按照一定的套路往寄存器里面写值 2&#xff09…

微服务之配置中心与服务跟踪

zookeeper 配置中心 实现的架构图如下所示,采取数据加载到内存方式解决高效获取的问题,借助 zookeeper 的节点监听机制来实现实时感知。 配置中心数据分类 事件调度(kafka) 消息服务和事件的统一调度,常用用 kafka …

vulnhub-Tre(cms渗透)

🐮博主syst1m 带你 acquire knowledge! ✨博客首页——syst1m的博客💘 😘《CTF专栏》超级详细的解析,宝宝级教学让你从蹒跚学步到健步如飞🙈 😎《大数据专栏》大数据从0到秃头👽&…

MATLAB画球和圆柱

1. 画球 修改了一下MATLAB的得到球的坐标的函数&#xff1a; GetSpherePoint function [xx,yy,zz] GetSpherePoint(xCenter,yCenter,zCenter,r,N) % 在[xCenter,yCenter,zCenter]为球心画一个半径为r的球,N表示球有N*N个面&#xff0c;N越大球的面越密集 if nargin < 4 …

Flink面试题与详解

Flink面试题目合集 从牛客网上找到的一些面试题&#xff0c;如果还有其他的&#xff0c;欢迎大家补充。 1、能否详细描述下Apache Flink的架构组件和其工作原理&#xff1f;请介绍一下Flink on YARN部署模式的工作原理。 官网图&#xff1a; 由两个部分组成&#xff0c;JM&am…