设计模式-策略(Strategy)模式
- 又被称为政策(方针)模式
- 策略模式(Strategy Design Pattern):封装可以互换的行为,并使用委托来决定要使用哪一个
- 策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换
- 用人话翻译后就是:运行时我给你这个类的方法传不同的 “key”,你这个方法就去执行不同的业务逻辑
- 解释:
- 现实世界例子:屠龙是一项危险的职业;有经验将会使它变得简单;经验丰富的屠龙者对不同类型的龙有不同的战斗策略
- 直白点说,策略模式允许在运行时选择最匹配的算法
- 在程序编程领域,策略模式(又叫政策模式)是一种启用在运行时选择算法的行为型软件设计模式
- 仔细一想,这不就是 if else 干的事吗
- 先直观的看下传统的多重 if else 代码:
- 再来看策略模式类图:
- 策略模式涉及到三个角色:
- Strategy:策略接口或者策略抽象类,用来约束一系列的策略算法(Context 使用这个接口来调用具体的策略实现算法)
- ConcreateStrategy:具体的策略类(实现策略接口或继承抽象策略类)
- Context:上下文类,持有具体策略类的实例,并负责调用相关的算法
- 先来看看最简单的策略模式 demo:
- 1-策略接口(定义策略)
- 2-具体的算法实现
- 3-上下文的实现
- 4-客户端使用(策略的使用)
- 这种策略的使用方式其实很死板,真正使用的时候如果还这么写,和写一大推 if-else 没什么区别,所以我们一般会结合工厂类,在运行时动态确定使用哪种策略
- 策略模式侧重如何选择策略、工厂模式侧重如何创建策略
- 策略模式的功能就是把具体的算法实现从具体的业务处理中独立出来,把它们实现成单独的算法类,从而形成一系列算法,并让这些算法可以互相替换
- 策略模式的重心不是如何来实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性
- 实际上,每个策略算法具体实现的功能,就是原来在 if-else 结构中的具体实现,每个 if-else 语句都是一个平等的功能结构,可以说是兄弟关系
- 策略模式呢,就是把各个平等的具体实现封装到单独的策略实现类了,然后通过上下文与具体的策略类进行交互
- 策略模式 = 实现策略接口(或抽象类)的每个策略类 + 上下文的逻辑分派
- 策略模式的本质:分离算法,选择实现
- 所以说,策略模式只是在代码结构上的一个调整,即使用了策略模式,该写的逻辑一个也少不了,到逻辑分派的时候,只是变相的 if-else
- 而它的优化点是抽象了出了接口,将业务逻辑封装成一个一个的实现类,任意地替换
- 在复杂场景(业务逻辑较多)时比直接 if-else 更好维护和扩展些
- 在策略模式中,我们可以自己定义谁来选择具体的策略算法,有两种:
- 客户端:当使用上下文时,由客户端选择,像我们上边的 demo
- 上下文:客户端不用选,由上下文来选具体的策略算法,可以在构造器中指定
- 避免冗长的if/else:
- 比如在出门旅游时:路线、交通工具的类型、天数、舱位等级、餐饮、住宿等等
- 每个节点在执行时,都需要根据预算进行不同的操作,从而引起大量的判断
- 增加一个策略,修改一个策略,都有可能牵一发而动全身
- 需要对所有状态进行回测
- 整个业务如图所示,所有的判断都耦合在业务流程内部,牵一发而动全身
- 使用策略模式
- 我们可以将某一条件(Type)下的逻辑,聚合封装到具体的策略类中
- 使用策略类后如图所示,每个的情况被封装聚合到单个策略类中,相互隔离
- 所以策略模式的作用主要体现在:
- 1-解耦策略的定义、创建和使用
- 控制代码的复杂度,让每个部分都不至于过于复杂、代码量过多
- 2-让复杂框架满足开闭原则
- 添加或者修改新策略的时候,最小化、集中化代码改动,减少引入 bug 的风险
- 策略的创建
- 通常会通过类型(type)来判断创建哪个策略来使用
- 这里,有两种创建方式
- if-else创建
- 适用于有状态的策略类,每次创建一个新的策略类给业务方使用
- 通过工厂模式里的Map进行创建
- 适用于无状态的策略类创建,大家共用一个策略类即可
- 本质上讲,是借助“查表法”,根据 type 查表替代根据 type 分支判断
- Java中的例子:
- 采用 Comparator 参数的 Collections.sort() 方法;根据 Comparator 接口的不同实现,对象会以不同的方式进行排序
- 使用策略模式应当:
- 许多相关的类只是行为不同;策略模式提供了一种为一种类配置多种行为的能力
- 你需要一种算法的不同变体;比如,你可能定义反应不用时间空间权衡的算法;当这些算法的变体使用类的层次结构来实现时就可以使用策略模式
- 一个算法使用的数据客户不应该对其知晓;使用策略模式来避免暴露复杂的,特定于算法的数据结构
- 一个类定义了许多行为,这些行为在其操作中展现为多个条件语句;移动相关的条件分支到它们分别的策略类中来代替这些条件语句
相关文章:

设计模式-策略(Strategy)模式
又被称为政策(方针)模式策略模式(Strategy Design Pattern):封装可以互换的行为,并使用委托来决定要使用哪一个策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中&#x…...

Star 4.1k!Gitee GVP开源项目!新一代桌面应用开发框架 ElectronEgg!
前言 随着现代技术的快速升级迭代及发展,桌面应用开发已经变得越来越普及。然而对于非专业桌面应用开发工程师在面对这项任务时,可能会感到无从下手,甚至觉得这是一项困难的挑战。 本篇文章将分享一种新型桌面应用开发框架 ElectronEgg&…...

node.js学习(简单聊天室)
在掘金查看该文章 1. TCP服务搭建 1.1 socket 先来粗略了解下socket 套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中&am…...
cfa一级考生复习经验分享系列(四)
备考CFA一级满打满算用了一个多月,每天八个小时以上。可能如果仅以通过为目标的话完全不用这样,看过太多类似于只看了一周就通过了考试又或是放弃了好几门飘过了考试的情况,我觉得这是不正确的考试状态,完全不必惊叹,踏…...

PPT插件-好用的插件-放映笔、绘图板-大珩助手
放映笔 幻灯片放映时,工具在幻灯片的左下方,本工具在幻灯片的右侧,可以移动,可以方便在右侧讲课时候使用 绘图板 可在绘图板上写签名、绘制图画、写字等等,点画笔切换橡皮擦,点插入绘图,将背景…...

弧形导轨的安装注意事项
随着弧形导轨的应用日渐普遍,在日常使用中总会遇到很多各种各样的问题,原因很多是安装不正确或者使用不恰当。不合理的使用不但不能充分发挥其价值还会导致使用寿命大打折扣,使企业造成不必要的损失,因此大伙有必要了解一些安装的…...

Elasticsearch优化-04
Elasticsearch优化 1、优化-硬件选择 Elasticsearch 的基础是 Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在 ES 的配置文件…/config/elasticsearch.yml中配置,如下: # #Path to directory where to store …...

Springboot+vue的公寓报修管理系统(有报告)。Javaee项目,springboot vue前后端分离项目
演示视频: Springbootvue的公寓报修管理系统(有报告)。Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的公寓报修管理系统,采用M(model&…...
uniapp腾讯地图路线规划
在uniapp中使用腾讯地图进行路线规划需要通过腾讯地图API进行操作。以下是基本的步骤: 在腾讯地图开放平台上注册账号,并创建应用获取API key。 在uniapp的项目中引入腾讯地图API的JS文件,例如在index.html中添加以下代码: <…...
Python 全栈体系【四阶】(五)
第四章 机器学习 三、数据预处理 1. 数据预处理的目的 去除无效数据、不规范数据、错误数据 补齐缺失值 对数据范围、量纲、格式、类型进行统一化处理,更容易进行后续计算 2. 预处理方法 2.1 标准化(均值移除) 让样本矩阵中的每一列的…...
原点处可微问题
文章目录 原点可微问题例例 原点可微问题 lim x → 0 , y → 0 f ( x , y ) − f ( 0 , 0 ) x 2 y 2 \lim\limits_{x\to{0},y\to{0}} \frac{f(x,y)-f(0,0)}{\sqrt{x^2y^2}} x→0,y→0limx2y2 f(x,y)−f(0,0) 0 0 0(1)是函数 f ( x , y ) f(x,y) f(x,y)在 ( 0 , 0 ) (…...

Flink+Kafka消费
引入jar <dependency><groupId>org.apache.flink</groupId><artifactId>flink-java</artifactId><version>1.8.0</version> </dependency> <dependency><groupId>org.apache.flink</groupId><artifactI…...
Seconds_Behind_Master越来越大,主从同步延迟
问题现象 发现从库mysql_slave的参数Seconds_Behind_Master越来越大。已排除主从服务器时间不一致;那么主要就判断两点:是io thread慢还是 sql thread慢?先观察show slave status\G 。 判断3个参数(参数后面的值是默认空闲时候的…...
除法求值[中等]
一、题目 给你一个变量对数组equations和一个实数值数组values作为已知条件,其中equations[i] [Ai, Bi]和values[i]共同表示等式Ai / Bi values[i]。每个Ai或Bi是一个表示单个变量的字符串。另有一些以数组queries表示的问题,其中queries[j] [Cj, Dj…...
新时代商业市场:AR技术的挑战与机遇并存
随着科技的不断发展,增强现实(AR)技术逐渐成为当今社会的一个重要组成部分。AR技术能够将虚拟世界与现实世界相结合,为人们提供更加丰富、多样化的体验。在新时代的社会商业市场中,AR技术也正逐渐被应用于各种商业活动…...
RHEL8中ansible的使用
编写ansible.cfg和清单文件ansible的基本用法 本章实验三台RHEL8系统(rhel801,rhel802,rhel803),其中rhel801是ansible主机 这里要确保ansible主机能够解析所有被管理的机器,这里通过配置/etc/hosts来实现…...

【1.6计算机组成与体系结构】存储系统
目录 1.层次化存储结构2.Cache2.1 Cache的介绍2.2 局部性原理2.3 Cache应用 1.层次化存储结构 由 ⬆ CPU:寄存器。 快 ⬆ Cache:按内容存取(相联存储器)。 到 ⬆内存(主存):DRAM。 慢 ⬆ 外存(辅存&#…...

TCP/UDP 协议
目录 一.TCP协议 1.介绍 2.报文格式 编辑 确认号 控制位 窗口大小 3.TCP特性 二.TCP协议的三次握手 1.tcp 三次握手的过程 三.四次挥手 2.有限状态机 四.tcp协议和udp协议的区别 五.udp协议 UDP特性 六.telnet协议 一.TCP协议 1.介绍 TCP(Transm…...
如何正确理解和使用 Golang 中 nil ?
目录 指针中的 nil 切片中的 nil map 中的 nil 通道中的 nil 函数中的 nil 接口中的 nil 避免 nil 相关问题的最佳实践 小结 在 Golang 中,nil 是一个预定义的标识符,在不同的上下文环境中有不同的含义,但通常表示“无”、“空”或“…...

IDEA新建jdk8 spring boot项目
今天新建spring boot项目发现JDK版本最低可选17。 但是目前用的最多的还是JDK8啊。 解决办法 Server URL中设置: https://start.aliyun.com/设置完成后,又可以愉快的用jdk8创建项目了。 参考 https://blog.csdn.net/imbzz/article/details/13469117…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...