设计模式--策略模式
目录
一.场景
1.1场景
2.2 何时使用
2.3个人理解
二. 业务场景练习
2.1业务:
2.2具体实现
2.3思路
三.总结
3.1策略模式的特点:
3.2策略模式优点
3.3策略模式缺点
一.场景
1.1场景
- 许多相关的类仅仅是行为有异,也就是说业务代码需要根据场景不同,切换不同的实现逻辑
- 一个类定义了多种行为,并且这些行为在类的操作中以多个条件语句的形式出现,也就是说代码中存在大量 if else 逻辑判断
2.2 何时使用
当一件任务可以使用不同的方式来完成,就可以使用策略模式
2.3个人理解
策略模式简单理解,应该是对于同一个业务功能,在不同的场景需求下提供不同的实现逻辑,来达到动态切换业务算法,满足不同场景的目的。同时它也有另外的好处,即优化代码结构,使其脱离大量逻辑判断,对外只提供 Context上下文,让算法与实际业务代码解耦,对使用者屏蔽底层实现逻辑。
对于我们根据不同的场景, 会定义应对不同场景相应的方法, 然而这些方法就是我们的策略,
策略模式 UML类图如下:

每个策略通过不同业务条件, 找到相应的算法类或逻辑类 , 最终得到想要的结果
二. 业务场景练习
2.1业务:
我们出行会根据不同的交通方式,制定不同的出行方式,比如:自驾、大巴车、高铁、飞机,而每出行方式就是一个定义一个策略。
2.2具体实现
首先:定义一个出行接口
/*** 描述:出行策略接口** @author QU* @date 2023/8/10*/
public interface TripModeStrategy {void tripModeStrategy();
}
策略一:自驾出行
/*** 描述: 自驾出行** @author QU* @date 2023/8/10*/
public class CarTripStrategy implements TripModeStrategy {@Overridepublic void tripModeStrategy() {System.out.println("自驾出行,花费200元,用时6个小时");}
}
策略二:大巴出行
/*** 描述: 公交车出行** @author QU* @date 2023/8/10*/
public class BusTripStrategy implements TripModeStrategy {@Overridepublic void tripModeStrategy() {System.out.println("公交车出行,花费100元,用时8个小时");}
}
策略三:高铁出行
/*** 描述: 高铁出行** @author QU* @date 2023/8/10*/
public class HighSpeedTripStrategy implements TripModeStrategy {@Overridepublic void tripModeStrategy() {System.out.println("高铁出行,花费500元,用时2.5小时");}
}
策略四:飞机出行
/*** 描述: 飞机出行** @author QU* @date 2023/8/10*/
public class AircraftTripStrategy implements TripModeStrategy {@Overridepublic void tripModeStrategy() {System.out.println("飞机出行,花费1000元,用时1个小时");}
}
制定策略输出类
package strategy.trip;/*** 描述: 策略输出** @author QU* @date 2023/8/10*/
public class TripMode {//注入策略private TripModeStrategy tripModeStrategy;TripMode(TripModeStrategy tripModeStrategy){this.tripModeStrategy=tripModeStrategy;}//输出具体策略public void executeTripStrategy(){tripModeStrategy.tripModeStrategy();}
}
制定策略工厂
/*** 描述: 策略工厂** @author QU* @date 2023/8/10*/
public class TripStrategyFactory {/*** 定义map存放所有策略.*/private static final Map<String,TripModeStrategy> TRIP_MODE_STRATEGY_MAP=new HashMap<>();/*** 使用静态方法来加载策略到map中*/static{TRIP_MODE_STRATEGY_MAP.put(TripEnum.CAR,new CarTripStrategy());TRIP_MODE_STRATEGY_MAP.put(TripEnum.BUS,new BusTripStrategy());TRIP_MODE_STRATEGY_MAP.put(TripEnum.HIGH_SPEED,new HighSpeedTripStrategy());TRIP_MODE_STRATEGY_MAP.put(TripEnum.AIRCRAFT,new AircraftTripStrategy());}/*** 使用静态方法通过模拟客户端传接的类型(参数)** @param key 策略类型(客户端用户选择的出行方式)* @return 具体某条策略*/public static TripModeStrategy tripModeStrategy(String key){TripModeStrategy tripModeStrategy = TRIP_MODE_STRATEGY_MAP.get(key);return tripModeStrategy;}
制定出行类型(出行常量)也可以认为我们wed或实际开发项目中的客户端选择的一条策略(用户选择的出行方式)
/*** 描述: 出行常量** @author QU* @date 2023/8/10*/
public class TripEnum {public static final String CAR="car";public static final String BUS="bus";public static final String HIGH_SPEED="high_speed";public static final String AIRCRAFT="aircraft";
}
测试类:
/*** 描述: 测试出行方式** @author QU* @date 2023/8/10*/
public class TripTest {public static void main(String[] args) {//自驾TripModeStrategy tripModeStrategy = TripStrategyFactory.tripModeStrategy(TripEnum.CAR);//大巴车//tripModeStrategy = TripStrategyFactory.tripModeStrategy(TripEnum.BUS);//高铁//tripModeStrategy = TripStrategyFactory.tripModeStrategy(TripEnum.HIGH_SPEED);//飞机tripModeStrategy = TripStrategyFactory.tripModeStrategy(TripEnum.AIRCRAFT);TripMode tripMode=new TripMode(tripModeStrategy);tripMode.executeTripStrategy();}
}
运行结果:这里根据程序运行选择就近原则(最后取变量值),预测是策略四飞机出行
结果:

2.3思路
- 首先根据业务制定出行策略(TripModeStrategy )
- 制定策略工厂将策略装进我们的静态代码块在工程启动已执行到map中,静态方法等待调用(tripModeStrategy(String key))
- 制定策略输出类,通过客户端选择出行方式去策略工厂中获取静态方法输出策略
三.总结
3.1策略模式的特点:
高内聚低耦合,可扩展,遵循ocp原则(开放封闭原则)
3.2策略模式优点
1.策略模式的功能就是通过抽象、封装来定义一系列的算法,使得这些算法可以相互替换,所以为这些算法定义一个公共的接口,以约束这些算法的功能实现。如果这些算法具有公共的功能,可以将接口变为抽象类,将公共功能放到抽象父类里面。
2.策略模式的一系列算法是可以相互替换的、是平等的,写在一起就是if-else组织结构,如果算法实现里又有条件语句,就构成了多重条件语句,可以用策略模式,避免这样的多重条件语句。
3.扩展性更好:在策略模式中扩展策略实现非常的容易,只要新增一个策略实现类,然后在使用策略实现的地方,使用这个新的策略实现就好了。
3.3策略模式缺点
1.客户端必须了解所有的策略,清楚它们的不同:
如果由客户端来决定使用何种算法,那客户端必须知道所有的策略,清楚各个策略的功能和不同,这样才能做出正确的选择,但是这暴露了策略的具体实现。
2.增加了对象的数量:
由于策略模式将每个具体的算法都单独封装为一个策略类,如果可选的策略有很多的话,那对象的数量也会很多。
3.只适合偏平的算法结构:
由于策略模式的各个策略实现是平等的关系(可相互替换),实际上就构成了一个扁平的算法结构。即一个策略接口下面有多个平等的策略实现(多个策略实现是兄弟关系),并且运行时只能有一个算法被使用。这就限制了算法的使用层级,且不能被嵌套。
相关文章:
设计模式--策略模式
目录 一.场景 1.1场景 2.2 何时使用 2.3个人理解 二. 业务场景练习 2.1业务: 2.2具体实现 2.3思路 三.总结 3.1策略模式的特点: 3.2策略模式优点 3.3策略模式缺点 一.场景 1.1场景 许多相关的类仅仅是行为有异,也就是说业务代码需要根据场景不…...
VSCode使用SSH无密码连接Ubuntu
VSCode使用SSH无密码连接Ubuntu 前提条件: 1. 能够正常使用vscode的Remote-ssh连接Ubuntu 2. Ubuntu配置静态ip(否则经常需要修改Remote-ssh的配置文件里的IP) 1. windows下 打开Win下的PowerShell,生成公钥和私钥 ssh-keygen…...
通过版本号控制强制刷新浏览器或清空浏览器缓存
背景介绍 在我们做 web 项目时,经常会遇到一个问题就是,需要 通知业务人员(系统用户)刷新浏览器或者清空浏览器 cookie 缓存的情况。 而对于用户而言,很多人一方面不懂如何操作,另一方面由于执行力问题&am…...
Redis系列(二):深入解读Redis的两种持久化方式
博客地址:blog.zysicyj.top Redis为什么要引入持久化机制 Redis引入持久化机制是为了解决内存数据库的数据安全性和可靠性问题。虽然内存数据库具有高速读写的优势,但由于数据存储在内存中,一旦服务器停止或崩溃,所有数据将会丢失…...
CNN之图像识别
文章目录 1. 图像识别1.1 模式识别1.2 图像识别的过程1.3 图像识别的应用 2. 深度学习发展2.1 深度学习为何崛起2.2 分类与检测2.3 常见的卷积神经网络 3. VGG3.1 VGG163.2 VGG16的结构:3.3 使用卷积层代替全连接3.4 1*1卷积的作用3.5 VGG16代码示例 4. 残差模型-Re…...
nvcc not found
检查cuda 安装成功 nvidia-smiCommand ‘nvcc’ not found, apt install nvidia-cuda-toolkitnvcc fatal : No input files specified; use option --help for more information # 注意是大写 V nvcc -V export PATH"/usr/local/cuda/bin:$PATH" expor…...
pdf怎么转换成jpg图片?这几个转换方法了解一下
pdf怎么转换成jpg图片?转换PDF文件为JPG图片格式在现代工作中是非常常见的需求,比如将PDF文件中的图表、表格或者图片转换为JPG格式后使用在PPT演示、网页设计等场景中。 【迅捷PDF转换器】是一款非常实用的工具,可以将PDF文件转换成多种不同…...
六轴机械臂码垛货物堆叠仿真
六轴机械臂码垛货物堆叠仿真 1、建立模型与仿真 clear,clc,close all addpath(genpath(.)) %建立模型参数如下: L(1) Link( d, 0.122, a , 0 , alpha, pi/2,offset,0); L(2) Link( d, 0.019 , a ,0.408 , alpha, 0,offset,pi/2); L(3) Link( d, …...
text-decoration 使用
text-decoration text-decoration 用于设置文本上的装饰性线条的外观。 它是 text-decoration-line、text-decoration-style、text-decoration-color 和text-decoration-thickness的缩写。 text-decoration: underline wavy red;text-decoration-line 设置文本装饰类型 可以…...
linux shell快速入门
linux shell快速入门 0 、前置1、简单使用 0 、前置 一安装linux的虚拟环境 1、简单使用 1、新建/usr/shell目录 2、新建hello.sh 文件 3、编写脚本文件# !/bin/bashecho "hello world"查看是否具备执行权限 新增执行权限 chomd x hello.sh执行hello.sh文件 /b…...
【Spring源码】小白速通解析Spring源码,从0到1,持续更新!
Spring源码 参考资料 https://www.bilibili.com/video/BV1Tz4y1a7FM https://www.bilibili.com/video/BV1iz4y1b75q bean的生命周期 bean–>推断构造方法(默认是无参构造,或指定的构造方法)–>实例化成普通对象(相当于ne…...
Unity 鼠标实现对物体的移动、缩放、旋转
文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine;public class ObjectManipulation : MonoBehaviour {// 缩放比例限制public float MinScale 0.2f;public float MaxScale 3.0f;// 缩放速率private float scaleRate 1f;// 新尺寸private float newScale;// 射线pri…...
67Class 的基本语法
Class 的基本语法 类的由来[constructor() 方法](https://es6.ruanyifeng.com/#docs/class#constructor() 方法)类的实例实例属性的新写法取值函数(getter)和存值函数(setter)属性表达式[Class 表达式](https://es6.ruanyifeng.c…...
企业数字化转型:无形资产占比测算(2007-2021年)
在本次数据中,参考张永珅老师的做法,利用无形资产占比测算数字化转型程度。 一、数据介绍 数据名称:企业数字化转型:无形资产占比 数据年份:2007-2021年 样本数量:32960条 数据说明:包括数…...
[centos]设置主机名
1、设置 hostnamectl set-hostname 名字 2、查看是否生效 hostnamectl status 3、打开一个新链接就可以了...
华为OD真题--新学习选址--带答案
2023华为OD统一考试(AB卷)题库清单-带答案(持续更新)or2023年华为OD真题机考题库大全-带答案(持续更新) 为了解新学期学生暴涨的问题,小乐村要建立所新学校 考虑到学生上学安全问题,需要所有学生家到学校的…...
Qt自定义对话框
介绍 自定义框主要通过对现有对话框QDialog类的派生,根据需求编写成员函数、重载信号函数、槽函数,进而实现在主QWidget中点击某个按钮后,一个对话框的弹出 流程 简化创建派生类 最后点击完成即可。 自定义ui界面,编写成员函数…...
Python 程序设计入门(018)—— format() 函数的用法详解
Python 程序设计入门(018)—— format() 函数的用法详解 目录 Python 程序设计入门(018)—— format() 函数的用法详解一、format() 函数的基本格式二、不提供 format_spec 参数三、设置字符串的对齐方式(align&#x…...
演进式架构
演进能力是一种元特征和保护其他所有架构特征的架构封装器IEEE 的软件架构定义中的41 视图模型。它关注不同角色的不同视角,将整个系统划分成了逻辑视图、开发视图、进程视图和物理视图架构师确定了可审计性、数据、安全性、性能、合法性和伸缩性是该应用的关键架构…...
OCP China Day 2023:五大社区齐聚,加速开源开放创新与落地
8月10日,2023年开放计算中国社区技术峰会(OCP China Day 2023)在北京举行。智慧时代,计算多元化、应用多样化、技术复杂化正驱动数据中心新一轮变革,开源开放社区已成为推动数据中心持续创新的重要力量,通过…...
VS Code官宣:全面支持Rust!
当"宇宙第一编辑器"遇上"内存安全的叛逆少年",这场联姻比想象中更甜~最近微软悄悄放了个大招:VSCode 要深度集成 rust-analyzer 了! 🎉 什么意思呢?以前你用 VSCode 写 Rust࿰…...
7个实用技巧:用immich实现自托管相册智能管理 | 隐私保护与高效共享指南
7个实用技巧:用immich实现自托管相册智能管理 | 隐私保护与高效共享指南 【免费下载链接】immich High performance self-hosted photo and video management solution. 项目地址: https://gitcode.com/GitHub_Trending/im/immich 你是否曾在数千张照片中艰难…...
电路分析不求人:手把手教你用戴维南定理搞定复杂电路(附Multisim仿真验证)
电路分析实战:用戴维南定理拆解复杂电路的全流程指南 当你面对一个布满电阻、电源和交叉连线的复杂电路图时,是否感到无从下手?戴维南定理就像一把瑞士军刀,能将这些看似棘手的电路简化为一个电压源和一个电阻的串联组合。但理论归…...
AI辅助开发:让快马AI成为你的编程搭档,迭代优化openclaw风格代码
今天想和大家分享一个开发小技巧:如何用AI辅助工具快速迭代优化代码。最近我在做一个数据抓取的小项目,需要实现类似openclaw的功能,正好用InsCode(快马)平台的AI功能试了试,效果出乎意料的好。 基础功能实现 最开始我只需要一个简…...
MSPM0G3507开发实战:Keil环境下多款仿真器(CMSIS-DAP/ST-Link/J-Link)与UniFlash下载全攻略
1. 为什么选择Keil开发MSPM0G3507? 对于嵌入式开发者来说,选择一款趁手的开发环境往往能事半功倍。我在多个项目中测试过不同开发环境后,发现Keil MDK在MSPM0G3507开发中确实有不少优势。首先是生态支持完善,TI官方提供的SDK和示例…...
从Linux驱动到HDF框架:手把手教你将CH9344 USB串口驱动适配OpenHarmony 4.0
从Linux到OpenHarmony:CH9344 USB串口驱动HDF适配全解析 当传统Linux驱动遇上新兴的OpenHarmony HDF框架,技术迁移的挑战与机遇并存。本文将深入探讨如何将成熟的CH9344 USB转串口驱动无缝迁移至OpenHarmony 4.0平台,为开发者提供一套可复用的…...
Go反射reflect包高级用法
Go语言反射机制探秘:深入reflect包高级用法 Go语言的反射机制通过reflect包为开发者提供了强大的运行时类型检查与操作能力。尽管反射会带来一定的性能开销,但在需要动态处理类型、实现泛型逻辑或构建框架时,它往往是不可替代的工具。本文将…...
ImportError: cannot import name ‘model_from_config‘ from ‘tensorflow.keras.models‘ 的解决方案
不慌,这是因为我们使用的 keras-rl2 库试图从 TensorFlow/Keras 中导入一个名为 model_from_config 的函数,但这个函数在新版本的 TensorFlow(通常是 2.16.0 及以上)中已经被移除或移动了。 在你的默认路径找到"C:\Users\HP…...
利用快马平台五分钟搭建openclaw部署原型,验证核心功能
最近在折腾一个开源机器人抓取框架openclaw,想快速验证它的核心功能。但传统部署流程实在太繁琐——要配环境、装依赖、调试各种版本冲突,经常花半天时间还没跑通。后来发现InsCode(快马)平台能一键生成部署原型,五分钟就搞定了测试环境&…...
别光记公式!用Python+OpenCV手把手带你标定相机内参外参(附完整代码)
别光记公式!用PythonOpenCV手把手带你标定相机内参外参(附完整代码) 在计算机视觉项目中,相机标定是构建三维感知系统的第一步。很多开发者能背诵内参矩阵的数学形式,却对如何用代码实际获取这些参数一头雾水。本文将用…...
