Java设计模式:行为型模式→策略模式

Java 策略模式详解

1. 定义

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,将每一个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。通过这种模式,可以在运行时选择特定的算法,从而实现灵活的行为。

2. 基本思想

策略模式的基本思想是将算法的实现与使用算法的环境相分离。使用策略模式,客户端可以根据具体需要选择的策略(算法)而不是硬编码到类中,并且可以在运行时根据不同的条件进行选择。通过这种方式,可以避免使用多重的条件判断语句,增强代码的可读性和可维护性。

3. 基本原理

策略模式主要由以下几个组成部分构成:

  • 策略接口(Strategy):定义所有支持的算法接口。
  • 具体策略类(Concrete Strategy):实现具体的算法。
  • 上下文类(Context):持有一个策略对象的引用,并通过该对象调用具体的策略算法。
  • 客户端(Client):使用上下文类来选择和执行具体策略。
    在这里插入图片描述

更多实用资源:

http://sj.ysok.net/jydoraemon 访问码:JYAM

4. 实现方式

4.1 基本实现

4.1.1 策略接口

首先定义一个策略接口,定义算法的标准:

public interface PaymentStrategy {void pay(int amount);
}
4.1.2 具体策略类

实现具体的支付方式,例如信用卡支付和 PayPal 支付:

public class CreditCardPayment implements PaymentStrategy {private String cardNumber;public CreditCardPayment(String cardNumber) {this.cardNumber = cardNumber;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);}
}public class PayPalPayment implements PaymentStrategy {private String email;public PayPalPayment(String email) {this.email = email;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using PayPal: " + email);}
}
4.1.3 上下文类

定义上下文类,并持有一个策略对象的引用:

public class PaymentContext {private PaymentStrategy paymentStrategy;public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void executePayment(int amount) {paymentStrategy.pay(amount);}
}
4.1.4 客户端代码

客户端代码,通过上下文类选择支付策略并执行:

public class Client {public static void main(String[] args) {PaymentContext paymentContext = new PaymentContext();// 使用信用卡支付PaymentStrategy creditCard = new CreditCardPayment("1234-5678-9876-5432");paymentContext.setPaymentStrategy(creditCard);paymentContext.executePayment(100); // 支付 100 单位// 使用 PayPal 支付PaymentStrategy payPal = new PayPalPayment("user@example.com");paymentContext.setPaymentStrategy(payPal);paymentContext.executePayment(200); // 支付 200 单位}
}

4.2 代码分析

  • 策略接口(PaymentStrategy):定义了所有具体支付策略实现的方法。
  • 具体策略类(CreditCardPayment 和 PayPalPayment):实现了不同的支付方式,具体执行支付逻辑。
  • 上下文类(PaymentContext):通过设置具体策略并执行支付,客户端不需要关心具体的支付实现。
  • 客户端:能够灵活选择和使用不同支付方式,体现策略的可替换性。

5. 工作流程

  1. 定义策略接口:创建一个接口以定义支持的策略算法。
  2. 实现具体策略类:编写不同的具体策略,分别实现策略接口。
  3. 创建上下文类:上下文类持有对策略对象的引用,负责调用策略的算法。
  4. 客户端选择策略:客户端通过上下文类来动态选择策略。

6. 变种

  1. 环境策略模式:在运行时,根据环境变化选择不同的策略,这是策略模式的常见变种。
  2. 组合策略模式:将多个策略组合在一起,形成复合的策略。

7. 实际应用

策略模式在实际开发中广泛应用,以下是一些典型的应用场景:

  1. 支付系统:根据不同支付方式的选择,选用不同的支付策略实现。
  2. 排序算法:采用不同的排序算法(快速排序、归并排序等)来处理数据,基于不同的条件选择最优排序策略。
  3. 图形处理:在图形应用中,根据不同的绘制需求使用不同的绘制算法。

8. 使用场景

使用策略模式的场景包括:

  • 当一个类需要根据不同条件选择算法时。
  • 需要在运行时动态更换算法实现时。
  • 避免在类中使用大量的条件语句时,能够提高代码的可读性和可维护性。

9. 优缺点

优点

  1. 灵活性:可以在运行时选择和切换策略。
  2. 避免条件判断:避免使用大量条件语句,提高代码的清晰度。
  3. 符合开闭原则:新的策略可以在不修改现有代码的情况下添加。

缺点

  1. 增加代码复杂性:增加了类的数量,使得系统结构更加复杂。
  2. 客户端需要了解策略:客户端需要知道许多策略的具体实现,以便于选择合适的策略。

10. 最佳实践

  1. 选择合适的接口设计:使策略的接口尽量简洁,便于理解和使用。
  2. 合理管理策略:在上下文中管理策略,避免混乱。
  3. 务必遵循单一职责原则:每个策略应当负责一个独立的功能,确保可维护性。

11. 注意事项

  1. 避免滥用策略模式:在不适合的情况下使用策略模式会导致系统过度复杂。
  2. 确保策略的独立性:策略之间应当保持独立,避免相互干扰。
  3. 考虑性能影响:在策略数量较多时,过多的策略切换可能会对性能产生一定影响。

12. 常见的误区

  • 策略模式仅能处理简单场景:策略模式不仅适用于简单的情况,也可以解决复杂的业务逻辑。
  • 认为策略模式会增加不必要的复杂性:在复杂的条件分支下,使用策略模式可以提高代码的清晰度。

13. 常见问题

  • 策略模式的核心组成部分是什么?

    • 策略模式的核心组成部分包括策略接口、具体策略类、上下文类和客户端。
  • 如何判断使用策略模式的适用性?

    • 当需要在运行时选择算法,并希望避免在类中使用复杂的条件判断时,可以考虑使用策略模式。
  • 策略模式与状态模式的区别是什么?

    • 策略模式用于选择算法,行为由对象决定;状态模式用于改变对象的状态,行为依赖于当前状态。

14. 总结

策略模式是一种极为灵活且有效的设计模式,适合在需要根据不同条件选择算法或行为的场景中应用。通过把不同的算法进行封装,并相互替换,策略模式增强了代码的可复用性和可维护性。在实际开发中,理解策略模式的基本原理、优缺点及使用场景,将帮助开发者设计出更具灵活性和可扩展性的Java应用程序。合理运用策略模式,可以显著提升系统的设计质量,为开发者提供更高效的架构设计方案。

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

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

相关文章

c++学习第十四天

提示:以下是本篇文章正文内容,下面案例可供参考。 //力扣代码 class Solution {const char* numStrArr[10]{"","","abc","def","ghi","jkl","mno","pqrs","tuv&q…

Python Matplotlib库:从入门到精通

Python Matplotlib库:从入门到精通 在数据分析和科学计算领域,可视化是一项至关重要的技能。Matplotlib作为Python中最流行的绘图库之一,为我们提供了强大的绘图功能。本文将带你从Matplotlib的基础开始,逐步掌握其高级用法&…

Vue平台开发三——项目管理页面

前言 对于多个项目的使用,可能需要进行项目切换管理,所以这里创建一个项目管理页面,登录成功后跳转这个页面,进行选择项目,再进入Home页面展示对应项目的内容。 一、实现效果图预览 二、页面内容 功能1、项目列表展…

常见字符串相关题目

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 优选算法专题 目录 14.最长公共前缀 5.最长回文子串 67.二进制求和 43.字符串相乘 14.最长公共前缀 题目: 编写一个函数来查…

网络安全 | F5-Attack Signatures-Set详解

关注:CodingTechWork 创建和分配攻击签名集 可以通过两种方式创建攻击签名集:使用过滤器或手动选择要包含的签名。  基于过滤器的签名集仅基于在签名过滤器中定义的标准。基于过滤器的签名集的优点在于,可以专注于定义用户感兴趣的攻击签名…

LibreChat

文章目录 一、关于 LibreChat✨特点 二、使用LibreChat🪶多合一AI对话 一、关于 LibreChat LibreChat 是增强的ChatGPT克隆:Features Agents, Anthropic, AWS, OpenAI, Assistants API, Azure, Groq, o1, GPT-4o, Mistral, OpenRouter, Vertex AI, Gemi…

基础项目实战——3D赛车(c++)

目录 前言一、渲染引擎二、关闭事件三、梯形绘制四、轨道绘制五、边缘绘制六、草坪绘制七、前后移动八、左右移动​九、曲线轨道​十、课山坡轨道​十一、循环轨道​十二、背景展示​十三、引入速度​十四、物品绘制​十五、课数字路障​十六、分数展示​十七、重新生成​十八、…

【C++】设计模式详解:单例模式

文章目录 Ⅰ. 设计一个类,不允许被拷贝Ⅱ. 请设计一个类,只能在堆上创建对象Ⅲ. 请设计一个类,只能在栈上创建对象Ⅳ. 请设计一个类,不能被继承Ⅴ. 请设计一个类,只能创建一个对象(单例模式)&am…

AAPM:基于大型语言模型代理的资产定价模型,夏普比率提高9.6%

“AAPM: Large Language Model Agent-based Asset Pricing Models” 论文地址:https://arxiv.org/pdf/2409.17266v1 Github地址:https://github.com/chengjunyan1/AAPM 摘要 这篇文章介绍了一种利用LLM代理的资产定价模型(AAPM)…

《网络数据安全管理条例》施行,企业如何推进未成年人个人信息保护(下)

文章目录 前言三、全流程推进未成年人个人信息保护1、处理前:未成年人个人信息处理的告知同意2、处理中:加强个人信息处理流程管理3、处理后:落实个人信息保护合规审计四、大型网络平台应每年发布社会责任报告前言 《网数条例》颁布前,我国已针对未成年人个人信息保护陆续…

games101-(5/6)

光栅化 投影完成之后,视图区域被确定在从[-1,1]的单位矩阵中,下一步就是光栅化 长宽比:ratio 垂直的可视角度:fild-of-view 可以看到的y 轴的范围,角度越小 越接近正交投影 屏幕坐标系 、 将多边形转化成像素 显示…

01学习预热篇(D6_正式踏入JVM深入学习前的铺垫)

目录 学习前言 一、虚拟机的结构 1. Java虚拟机参数设置 2. java 堆 3. 出入栈 4. 局部变量表 1> 局部变量的剖析 2> 局部变量的回收 5. 操作数栈 1> 常量入栈指令 2> 局部变量值转载到栈中指令 3> 将栈顶值保存到局部变量中指令 6. 帧数据区 7. 栈…

在亚马逊云科技上用Stable Diffusion 3.5 Large生成赛博朋克风图片(下)

背景介绍 在2024年的亚马逊云科技re:Invent大会上提前预告发布的Stable Diffusion 3.5 Large,现在已经在Amazon Bedrock上线了!各位开发者们现在可以使用该模型,根据文本提示词文生图生成高质量的图片,并且支持多种图片风格生成&…

Redis学习之哨兵二

一、API 1.sentinel masters:展示被监控的主节点状态及相关的统计信息 2.sentinel master <master name>:展示指定的主节点的状态以及相关的统计信息 3.sentinel slaves <master name>:展示指定主节点的从节点状态以及相关的统计信息 4.sentinel sentinels <mas…

如何把obsidian的md文档导出成图片,并加上文档属性

上篇关于这个插件PKMer_Obsidian 插件&#xff1a;Export Image plugin 一键将笔记转换为图片分享的文章 如何把obsidian的md文档导出成图片&#xff0c;并加上水印-CSDN博客 如何导出图片的时候让文档属性也显示出来&#xff0c;啊啊&#xff0c;这个功能找了一晚上&#xf…

新年祝词(原创)

新年将至&#xff0c;福进万户。 家家团圆&#xff0c;事事顺心。 喜迎财神&#xff0c;多寿添金。 瑞兽迎春&#xff0c;炮竹声起。 趋吉避凶&#xff0c;蛇年大吉。 中华崛起&#xff0c;人人自强。 天下大同&#xff0c;百姓富足。 有情有义&#xff0c;平易近人。 …

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.19 排序革命:argsort的十大高阶用法

1.19 排序革命&#xff1a;argsort的十大高阶用法 目录 #mermaid-svg-Qu8PcmLkIc1pOQJ7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Qu8PcmLkIc1pOQJ7 .error-icon{fill:#552222;}#mermaid-svg-Qu8PcmLkIc1pOQJ…

TensorFlow实现逻辑回归模型

逻辑回归是一种经典的分类算法&#xff0c;广泛应用于二分类问题。本文将介绍如何使用TensorFlow框架实现逻辑回归模型&#xff0c;并通过动态绘制决策边界和损失曲线来直观地观察模型的训练过程。 数据准备 首先&#xff0c;我们准备两类数据点&#xff0c;分别表示两个不同…

Unity git版本管理

创建仓库的时候添加了Unity的.gitignore模版&#xff0c;在这个时候就能自动过滤不需要的文件 打开git bash之后&#xff0c;步骤git版本管理-CSDN博客 如果报错&#xff0c;尝试重新进git 第一次传会耗时较长&#xff0c;之后的更新就很快了

【AI论文】扩散对抗后训练用于一步视频生成总结

摘要&#xff1a;扩散模型被广泛应用于图像和视频生成&#xff0c;但其迭代生成过程缓慢且资源消耗大。尽管现有的蒸馏方法已显示出在图像领域实现一步生成的潜力&#xff0c;但它们仍存在显著的质量退化问题。在本研究中&#xff0c;我们提出了一种在扩散预训练后针对真实数据…