23种设计模式(三)——策略模式【组件协作】

news2024/9/24 11:32:41

文章目录

    • 意图
    • 什么时候使用策略
      • 真实世界类比
    • 策略模式的实现
    • 策略模式的优缺点

亦称:Strategy

意图

定义了一组策略,分别在不同类中封装起来,每种策略都可以根据当前场景相互替换,从而使策略的变化可以独立于操作者。比如我们要去某个地方,会根据距离的不同(或者是根据手头经济状况)来选择不同的出行方式(共享单车、坐公交、滴滴打车等等),这些出行方式即不同的策略。

在这里插入图片描述

什么时候使用策略

主要解决在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

  • 针对同一问题的多种处理方式,仅仅是具体行为有差别时;
  • 需要安全地封装多种同一类型的操作时;
  • 同一抽象类有多个子类,而客户端需要使用if-else 或者 switch-case 来选择具体子类时

真实世界类比

在这里插入图片描述

假如你需要前往机场。 你可以选择乘坐公共汽车、 预约出租车或骑自行车。 这些就是你的出行策略。 你可以根据预算或时间等因素来选择其中一种策略。

策略模式的实现

1、抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
2、具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
3、环境(Context)类:持有一个策略类的引用,最终给客户端调用。

class Strategy
{
public:
	virtual ~Strategy() = default;
	virtual std::string DoAlgorithm(std::string strViewData) const = 0;
};

/**
 * The Context defines the interface of interest to clients.
 */
class Context
{
	/**
	 * @var Strategy The Context maintains a reference to one of the Strategy
	 * objects. The Context does not know the concrete class of a strategy. It
	 * should work with all strategies via the Strategy interface.
	 */
private:
	std::unique_ptr<Strategy> strategy_;
	/**
	* Usually, the Context accepts a strategy through the constructor, but also
	* provides a setter to change it at runtime.
	*/
public:
	explicit Context(std::unique_ptr<Strategy> &&strategy = {}) : strategy_(std::move(strategy))
	{
	}
	/**
	 * Usually, the Context allows replacing a Strategy object at runtime.
	 */
	void SetStrategy(std::unique_ptr<Strategy> &&strategy)
	{
		strategy_ = std::move(strategy);
	}
	/**
	* The Context delegates some work to the Strategy object instead of
	* implementing +multiple versions of the algorithm on its own.
	*/
	void DoSomeBusinessLogic() const
	{
		if (strategy_) {
			std::cout << "Context: Sorting data using the strategy (not sure how it'll do it)\n";
			std::string strResult = strategy_->DoAlgorithm("aecbd");
			std::cout << strResult << "\n";
		}
		else {
			std::cout << "Context: Strategy isn't set\n";
		}
	}
};

/**
* Concrete Strategies implement the algorithm while following the base Strategy
* interface. The interface makes them interchangeable in the Context.
*/
class ConcreteStrategyA :public Strategy
{
public:
	std::string DoAlgorithm(std::string strViewData) const override
	{
		std::string strResult(strViewData);
		std::sort(std::begin(strResult), std::end(strResult));

		return strResult;
	}
};

class ConcreteStrategyB :public Strategy
{
public:
	std::string DoAlgorithm(std::string strViewData) const override
	{
		std::string strResult(strViewData);
		std::sort(std::begin(strResult), std::end(strResult), std::greater<>());

		return strResult;
	}
};

策略模式的优缺点

优点缺点
你可以在运行时切换对象内的算法。如果你的算法极少发生改变, 那么没有任何理由引入新的类和接口。 使用该模式只会让程序过于复杂。
你可以将算法的实现和使用算法的代码隔离开来。客户端必须知晓策略间的不同——它需要选择合适的策略。
你可以使用组合来代替继承。许多现代编程语言支持函数类型功能, 允许你在一组匿名函数中实现不同版本的算法。 这样, 你使用这些函数的方式就和使用策略对象时完全相同, 无需借助额外的类和接口来保持代码简洁。
开闭原则。 你无需对上下文进行修改就能够引入新的策略。

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

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

相关文章

Type-challenges: tuple to object / union

type-challenges/README.zh-CN.md at main type-challenges/type-challenges GitHub https://github.com/TIMPICKLE/type-challenges/blob/main/questions/00010-medium-tuple-to-union/README.zh-CN.md lets do it , mate! 首先概念澄清&#xff1a; JS&#xff1a; con…

TKE 注册节点,IDC 轻量云原生上云的最佳路径

林顺利&#xff0c;腾讯云原生产品经理&#xff0c;负责分布式云产品迭代和注册节点客户扩展&#xff0c;专注于云原生混合云新形态的推广实践。 背景 企业在持续业务运维过程中&#xff0c;感受到腾讯云 TKE 带来的便捷性和极致的使用体验&#xff0c;将新业务的发布以及老业…

回答问题】ChatGPT上线了!给我推荐20个比较流行的图像全景分割模型

给我推荐20个比较流行的图像全景分割模型 好的&#xff0c;这是 20 个比较流行的图像全景分割模型&#xff1a;DeepLabv3 PSPNet FCN U-Net Mask R-CNN UNet SegNet ENet ICNet ENet GCN DANet BiSeNet DenseASPP DenseASPPv2 DenseASPPv3 DenseASPPv4 DenseASPPv5 DenseASPPv…

Redis数据持久化

数据持久化 RDB (Redis DataBase) 在指定的时间间隔内将内除中的数据集快照写入磁盘&#xff0c;即Snapshot快照。 备份如何执行 Redis会单独创建&#xff08;fork&#xff09;一个子进程来执行持久化&#xff0c;会先将数据写入到一个临时文件&#xff0c;待持久化过程结束…

【嵌入式Linux环境搭建-02】虚拟机安装Ubuntu20系统

虚拟机安装 Ubuntu 系统 前面用的VMware15.5&#xff0c;安装完Ubuntu20.04报错&#xff0c;试了以下方法都不行。 建议直接安装VMware16.2&#xff0c;步骤和上面一样 报错 解决&#xff1a;VMware Workstation 与 Device/Credential Guard 不兼容_山顶夕景的博客-CSDN博客…

JS阻止事件冒泡的方法*基础原理与运用

目录 事件冒泡html布局css样式代码 非标准写法&#xff1a;IE6-8 利用事件对象cancelBubble属性 标准写法&#xff1a;利用事件对象里面的stopPropagation()方法 下拉菜单 操作方法 事件冒泡html布局css样式代码 首先创建三个嵌套的方块&#xff0c;便于案例分析 <div…

NewSQL如何解决高可用、分片?

1 什么是New SQL&#xff1f; 无论你其他方面做的比Old SQL好再多&#xff0c;SQL和ACID是刚需&#xff0c;这个命你革不掉的。你不支持SQL&#xff0c;就不会有多少人用。所以近几年很多之前不支持SQL的数据库&#xff0c;都开始支持SQL了&#xff0c;甚至于像Spark、Flink这…

自然语言处理 第十章 信息抽取 复习

信息抽取信息抽取复习重点&#xff1a;信息抽取概述从任务内容分为&#xff1a;从处理文档类型分为&#xff1a;从发展时间和处理文档分为&#xff1a;实体识别与抽取限定域命名实体识别基于规则或字典的方法 &#xff1a;规则模版&#xff08;字典&#xff09;匹配统计学习方法…

23.1、Java中的类加载器反射模块化

1.类加载器 1.1类加载 类加载的描述 当程序要使用某个类时&#xff0c;如果该类还未被加载到内存中&#xff0c;则系统会通过类的加载&#xff0c;类的连接&#xff0c;类的初始化这三个步骤来对类进行初始化。如果不出现意外情况&#xff0c;JVM将会连续完成这三个步骤&#…

spring boot 七:SpringBoot自定义配置Jackson的ObjectMapper

spring boot 七&#xff1a;SpringBoot2.5.4自定义配置Jackson的ObjectMapper 1 前言 SpringBoot底层默认使用的自动依赖注入&#xff0c;即spring-boot-autoconfigure包的META-INF下&#xff0c;存在spring.factories文件&#xff0c;里面有自动注入的jackson自动配置类。在…

[数据结构基础]栈和队列的结构及接口函数

一. 栈 1.1 栈的概念及结构 栈是一种特殊的线性表&#xff0c;其只允许在固定的一段进行插入和删除元素的操作。进行数据插入和删除的一端成为栈顶&#xff0c;另一端称为栈底。栈结构中的数据遵循先进后出原则&#xff08;LIFO&#xff1a;Last in First Out&#xff09;&am…

03 Hive概述

Hive概述1、什么是Hive2、Hive优缺点3、Hive架构原理4、Hive 和 数据库比较5、Hive计算引擎1、什么是Hive 由Facebook开源用于解决海量结构化日志的数据统计工具。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供 类SQ…

如何在外籍人员子女学校和同事有效工作

香港 (Xinwengao.com) — PD Academia 的 Henry Wong 在新加坡出生长大&#xff0c;在美国接受高等教育&#xff0c;现在在美国半退休。他在中国生活了16年。他与许多西方人和中国人一起工作。他始终将自己视为东方与西方的交汇点&#xff0c;是学术界与行政部门之间的桥梁。他…

刷油漆【中等】

在一个8 \times 8 的网格中&#xff0c;一些水平的行被涂成红色&#xff0c;一些垂直的列被涂成蓝色&#xff0c;条纹是按顺序画的&#xff0c;一个接着一个。绘制条纹时它会重新绘制它所经过的所有单元格。(原理跟刷油漆一样)现在你需要确定最后一个上色的是什么颜色红色条纹是…

静态路由配置

获取未知网段的路由信息&#xff1a; 静态路由&#xff1a;由网络管理员手工配置的路由条目 动态路由&#xff1a;所有路由器上开启同一种路由协议&#xff0c;之后&#xff0c;通过路由器之间沟通&#xff0c;协商&#xff0c;最终计算生成路由条目。 静态路由的优点&#xf…

MySQL2-初识MySQL

目录 1.数据库 1.1.什么是数据库? 1.2.为什么要用数据库&#xff1f; 1.2.1.数据存储的发展史 1.2.2.文件存储的缺点 1.3.数据库分类 1.3.1.关系型数据库&#xff08;RDBMS&#xff09; 1.3.2.非关系型数据库&#xff08;了解&#xff09; 1.3.3.关系型数据库和非关系…

STM32——TIM简介与TIM中断

文章目录一、TIM简介二、定时器类型基本定时器通用定时器高级定时器三、定时中断基本结构四、时序图预分频器时序计数器时序计数器无预装时序计数器有预装时序RCC时钟树五、定时器定时中断六、定时器外部时钟七、定时器库函数&#xff08;tim.h&#xff09;一、TIM简介 TIM&am…

【设计模式篇】设计模式3类23种

创建型模式 创建型模式提供了创建对象的机制&#xff0c; 能够提升已有代码的灵活性和可复用性。 这里面比较重要和经常用到时单例模式、工厂模式和原型模式。 单例模式 单例模式是一种创建型设计模式&#xff0c; 让你能够保证一个类只有一个实例&#xff0c; 并提供一个访问…

antd 动态增减表单项的使用

需求 首先这是基于antd的Form组件&#xff0c;需求1&#xff1a; 单选按钮组 选择设置时间 展示时间选择器需求2&#xff1a; 动态添加时间选择器(最多添加10个、时间为空校验、时间段重叠校验)需求3&#xff1a; 开关需求4&#xff1a;编辑时赋值 1. 单选钮组 <Radio.Gro…

4.6.1、路由选择协议概述

1、静态/动态路由 2、主要特点 因特网所采用的路由选择协议的主要特点 例如&#xff1a;一个较大的因特网提供商就可划分为一个自治系统 在自治系统内部和外部采用不同类别的路由选择协议&#xff0c;分别进行路由选择 3、分层次的路由选择协议 如下所示&#xff0c;将网络…