设计模式-策略模式详解

news2024/11/29 0:50:41

1. 背景

  在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等,超市促销可以釆用打折、送商品、送积分等方法。

  在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。如果使用多重条件转移语句实现(即硬编码),不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。如果采用策略模式就能很好解决该问题。

2. 定义和特点

(1) 定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

(2) 优点:

 A. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。

 B. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。

 C. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。

 D. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。

 E. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

(3) 缺点

 A. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。

 B. 策略模式造成很多的策略类。

3.具体实现

(1) 模式的结构

 策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

 A. 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

 B. 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

 C. 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

结构图:

(2) 应用场景

  不同场景下需要对两个数进行运算(加减乘除),这个时候就可以使用策略模式。首先声明一个策略接口IStrategy,用于定义策略的计算方法; 然后声明具体的策略类(加减乘除),均实现这个IStrategy策略接口;最后声明一个Context策略选择类,用户客户端调用执行。

更多C++后台开发技术点知识内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。

C/C++Linux服务器开发高级架构师/C++后台开发架构师免费学习地址

【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以点击领取

(3) 代码实操

策略接口和具体的策略类

    /// <summary>
    /// 抽象策略结构
    /// </summary>
    public interface IStrategy
    {
        /// <summary>
        /// 策略计算方法
        /// </summary>
        /// <param name="num1"></param>
        /// <param name="num2"></param>
        /// <returns></returns>
        public int DoOperation(int num1, int num2);
    }
    /// <summary>
    /// 1、加法策略
    /// </summary>
    public class OperationAdd : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            return num1 + num2;
        }
    }
    /// <summary>
    /// 2、减法策略
    /// </summary>
    public class OperationSubtract : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            return num1 - num2;
        }
    }
    /// <summary>
    /// 3、乘法策略
    /// </summary>
    public class OperationMultiply : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            return num1 * num2;
        }
    }
    /// <summary>
    /// 4、除法策略
    /// </summary>
    public class OperationDivision : IStrategy
    {
        public int DoOperation(int num1, int num2)
        {
            return num1 / num2;
        }
    }

策略选择类

    /// <summary>
    /// 策略选择类
    /// </summary>
    public class Context
    {
        private IStrategy strategy;

        public Context(IStrategy strategy)
        {
            this.strategy = strategy;
        }

        public int executeStrategy(int num1, int num2)
        {
            return strategy.DoOperation(num1, num2);
        }
    }

测试

{
                Context context = new Context(new OperationAdd());
                Console.WriteLine("10 + 5 = " + context.executeStrategy(10, 5));

                context = new Context(new OperationSubtract());
                Console.WriteLine("10 - 5 = " + context.executeStrategy(10, 5));

                context = new Context(new OperationMultiply());
                Console.WriteLine("10 * 5 = " + context.executeStrategy(10, 5));

                context = new Context(new OperationDivision());
                Console.WriteLine("10 / 5 = " + context.executeStrategy(10, 5));

            }

运行结果

4. 适用场景分析

 A. 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。

 B. 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。

 C. 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。

D. 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。

 E. 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

原文链接:https://www.cnblogs.com/yaopengfei/p/13444014.html

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

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

相关文章

Java数据结构中栈和队列深度解析

栈和队列使用的范围很广&#xff0c;本篇用来深度解析Java数据结构中的栈和队列的深度解析&#xff0c;栈和队列都能用单向或双向链表来实现哦&#xff0c;希望可以帮助各位&#xff01; 文章目录 目录 一、栈 1.1栈的概念 1.2栈的使用 1.3栈的自定义顺序栈实现 1.4栈的练习题…

本机信息收集

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a; 内网安全 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远…

【JavaEE】Java中复杂的Synchronized关键字

目录 一、synchronized的特性 &#xff08;1&#xff09;互斥 &#xff08;2&#xff09;刷新内存 &#xff08;3&#xff09;可重入 二、synchronized的使用 &#xff08;1&#xff09;修饰普通方法 &#xff08;2&#xff09;修饰静态方法 &#xff08;3&#xff09;修…

计网之初识网络(理解网络传输的基本流程)

文章目录一. 网络发展史二. IP地址和端口号三. 计算机网络分层1. 什么是网络协议2. OSI七层网络模型3. TCP/IP五层网络模型4. 数据在各个层的传输过程5. 网络设备所在分层一. 网络发展史 &#x1f342;独立模式(单机模式) 我们最初的计算机是在单机模式下使用的, 此时的计算机…

遇到“独自开”,开发出属于自己一套专属系统的时代还会远吗?

目录 一、前言 二、介绍 三、详细介绍 四、总结 一、前言 哈喽&#xff0c;大家好&#xff0c;我是追&#xff0c;看到标题独自开时&#xff0c;可能此处会有疑问了。独自开&#xff1f;半山居士王安石的“墙角数枝梅&#xff0c;凌寒独自开”&#xff1f;哈哈&#xff0c;…

北京化工大学2/7寒假集训题解(>1800)

目录 A-Fence B-D again​ C-Cut the Sequence D-Parade E-trade A-Fence #include<algorithm> #include<string.h> #include<stdio.h> #include<queue> using namespace std; struct nob {int v,p;bool operator <(const nob &a)const{retu…

网络协议(四):网络分类、ISP、上网方式、公网私网、NAT

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 目录…

【沁恒WCH CH32V307V-R1开发板两路ADC读取实验】

【沁恒WCH CH32V307V-R1开发板两路ADC读取实验】1. 前言2. 软件配置2.1 安装MounRiver Studio3. ADC项目测试3.1 打开ADC工程3.2 编译项目4. 下载验证4.1 接线4.2 演示效果5. 小结1. 前言 ADC 模块包含 2 个 12 位的逐次逼近型的模拟数字转换器&#xff0c;最高 14MHz 的输入时…

2022年这5款熟悉的软件退出了历史舞台

在过去的一年里&#xff0c;有很多新产品发布&#xff0c;当然也有很多产品与我们就此别过。这些产品曾陪伴我们的生活&#xff0c;给我们带来欢乐&#xff0c;帮助我们成长。所以本文将盘点一下在2022年和我们告别的产品。1.微软IE浏览器IE浏览器1995年8月16日正式上线&#x…

window 安装debian的Linux系统+一些环境初始化

文章目录一、安装&#xff1a;1、安装WSL22、微软商店搜索debian安装&#xff1a;3、也可以官方安装&#xff1a;二、更改镜像源1、查看debian系统版本&#xff1a;2、修改3、升级三、安装zsh1&#xff1a;检查2、安装zsh3、安装oh-my-zsh4、安装插件5、配置文件~/.zshrc:6、配…

软件工程详细知识点(下)

文章目录七、面向对象的分析设计1、面向对象分析&#xff08;OOA&#xff09;2、面向对象设计&#xff08;OOD&#xff09;八、编码1、程序设计语言九、软件测试十、软件维护十一、软件项目管理RUP&#xff08;统一软件开发过程&#xff09;面向对象编程和面向对象设计的五个基…

【C++STL】双向循环链表与其迭代器的深度剖析及实现(百字短文速通)

1&#xff0c;双向循环链表基本结构的实现&#xff08;不包含需要迭代器的部分&#xff09;先用struct封装链表的节点&#xff0c;这里我们仅需要提供一个构造函数即可&#xff0c;并且构造函数必须提供缺省值&#xff0c;因为会有如下使用场景&#xff1a;new Node();此时需要…

crawler爬虫抓取数据

crawler爬虫实现 学习目标&#xff1a; 了解 crawler爬虫运行流程了解 crawler爬虫模块实现 1. crawler功能 初始化driver输入公司名称,并点击判断是否需要验证如果需要验证&#xff0c;获取验证图片并保存获取打码坐标点击验证图片判断查询结果选择第一条查询结果获取主要信…

电脑自带的录屏软件在哪?图文教学,教你如何快速录屏

很多小伙伴或许都听说过电脑有一款自带的录屏软件&#xff0c;但却不知道这款录屏软件在哪里。电脑自带的录屏软件在哪&#xff1f;其实很简单&#xff0c;如果你的电脑是Win10或者Win11的电脑&#xff0c;那么就可以使用电脑自带的录屏软件&#xff0c;一起跟着小编来看看吧。…

初次认识C++类

目录 前言&#xff1a; 面向过程和面向对象的区别&#xff1a; C语言&#xff1a; C&#xff1a; 类的引入&#xff1a; 类的定义&#xff1a; 类的权限&#xff1a; 类的作用域&#xff1a; 类的实例化&#xff1a; 类的大小计算&#xff1a; 空类或则只…

急速肝了一波ChatGPT,听说阿里面试题都没问题~

目录前言注册步骤&#xff1a;最后总结前言 互联网圈子里面ChatGPT现在实在是太火了&#xff0c;但是你还没用过&#xff1f;我只能说你OUT了&#xff0c;ChatGPT是什么呢&#xff1f; 由人工智能实验室OpenAI发布的对话式大型语言模型ChatGPT引爆中文互联网。它可以与人类轻松…

2022年ts学习记录

以下记录的是&#xff0c;我在学习中的一些学习笔记&#xff0c;这篇笔记是自己学习的学习大杂烩&#xff0c;主要用于记录&#xff0c;方便查找一、TS 是什么 &#xff1f;##1、简介TS&#xff1a;是TypeScript的简称&#xff0c;是一种由微软开发的自由和开源的编程语言。ts …

朗润外盘国际期货:SC原油市场情绪回暖领涨期市

今日值得回溯的三个行情&#xff1a;①SC原油主力合约今日收高4.23%&#xff0c;研报建议仍以震荡行情对待&#xff1f;②沪锡主力合约收涨3.20%&#xff0c;现在做多合适吗&#xff1f;③鸡蛋主力合约收跌1.32%&#xff0c;研报称这只是小幅回调。 【今日期市盘面概况】 整体…

深度学习 Day25——使用Pytorch实现彩色图片识别

深度学习 Day25——使用Pytorch实现彩色图片识别 文章目录深度学习 Day25——使用Pytorch实现彩色图片识别一、前言二、我的环境三、前期工作1、导入依赖项和设置GPU2、下载数据3、加载数据4、数据可视化四、构建CNN网络结构1、函数介绍2、构建CNN并打印模型3、可视化模型结构五…

Docker安装EalasticSearch、Kibana,安装Elasticvue插件

使用Docker快速安装部署ES和Kibana的前提&#xff1a;首先需要确保已经安装了Docker环境。 如果没有安装Docker的话&#xff0c;先在Linux上安装Docker。 有了Docker环境后&#xff0c;就可以使用Docker安装部署ES和Kibana了 一、安装ES 1、拉取EalasticSearch镜像 docker p…