当前位置: 首页 > news >正文

【设计模式】Java 设计模式之模板策略模式(Strategy)

策略模式详解:模式结构、实现与应用场景

一、策略模式概述

策略模式是一种行为设计模式,它使得算法可以独立于使用它的客户端变化。策略模式使得算法可以在运行时切换,从而增强了系统的灵活性和可维护性。在策略模式中,我们定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。

二、策略模式结构

策略模式包含三个主要角色:

  1. Context(上下文):它用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。
  2. Strategy(策略):这是一个策略接口,定义了所有支持的算法的公共接口。
  3. ConcreteStrategy(具体策略):实现了Strategy接口,封装了具体的算法或行为。

三、策略模式的实现方式

策略模式的实现通常包括定义一个策略接口和多个实现了该接口的具体策略类。上下文类持有对策略对象的引用,并在运行时根据需要动态地切换策略对象。

示例代码

// 策略接口
public interface PaymentStrategy {void pay(double amount);
}// 具体策略A:信用卡支付
public class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paying by credit card: " + amount);// 信用卡支付逻辑}
}// 具体策略B:现金支付
public class CashPayment implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("Paying by cash: " + amount);// 现金支付逻辑}
}// 上下文类
public class PaymentContext {private PaymentStrategy paymentStrategy;public PaymentContext(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void executePayment(double amount) {paymentStrategy.pay(amount);}
}

四、策略模式的优点

  1. 开闭原则:策略模式对扩展开放,对修改封闭。增加新的策略只需要增加新的策略类,无需修改已有代码。
  2. 灵活性:策略模式使得算法可以独立于使用它的客户端变化,客户端可以动态地选择使用哪种策略。
  3. 简化单元测试:策略模式使得每一个算法都有自己的类,这样算法可以独立地进行单元测试。

五、策略模式的缺点

  1. 客户端必须知道策略的存在:客户端需要了解不同策略的存在,并显式地选择使用哪种策略。
  2. 策略类可能过多:当策略数量较多时,会导致策略类数量膨胀,增加系统复杂性。

六、常见的应用场景

  1. 排序算法:不同的排序算法(如冒泡排序、快速排序等)可以作为不同的策略实现。
  2. 日志记录:不同的日志记录级别(如DEBUG、INFO、ERROR)可以使用不同的日志记录策略。
  3. 支付方式:在电商系统中,不同的支付方式(如信用卡支付、现金支付、第三方支付等)可以作为不同的策略实现。

七、应用案例解读

以电商系统的支付功能为例,策略模式可以很好地应用。电商系统需要支持多种支付方式,每种支付方式都有自己的处理逻辑。使用策略模式,我们可以定义一个支付策略接口,并为每种支付方式实现一个具体的策略类。在支付流程中,根据用户选择的支付方式,动态地创建并使用相应的支付策略对象进行支付操作。这样,当需要添加新的支付方式时,只需实现新的策略类并集成到系统中即可,无需修改已有的代码。

八、总结

策略模式是一种强大而灵活的设计模式,它允许我们在运行时动态地改变对象的行为。通过封装算法或行为到独立的策略类中,我们提高了代码的复用性和可维护性。然而,策略模式也有其局限性,需要在具体应用场景中权衡其优缺点,合理使用。

九、注意事项

在使用策略模式时,需要注意以下几点:

  1. 策略类数量控制:避免创建过多的策略类,以免增加系统的复杂性。可以通过合理的策略划分和合并来减少策略类的数量。
  2. 策略切换逻辑:确保策略切换的逻辑正确无误,避免出现策略切换错误或遗漏的情况。
  3. 策略配置管理:对于需要动态配置策略的场景,需要提供合理的策略配置管理机制,方便用户进行策略的选择和切换。

十、未来展望

随着技术的不断发展和业务场景的日益复杂,策略模式将在更多领域得到应用
十一、策略模式与其他设计模式的协同

策略模式经常与其他设计模式结合使用,以构建更健壮和灵活的系统。例如,策略模式可以与工厂模式结合,用于创建具体的策略对象。工厂模式可以根据需要动态地生成并返回策略对象,从而进一步解耦策略的选择和创建过程。

十二、策略模式的性能考虑

虽然策略模式提供了高度的灵活性和可扩展性,但在某些情况下,频繁地切换策略可能会带来性能开销。因此,在设计系统时,需要权衡策略模式带来的好处和可能带来的性能损失,确保系统的整体性能满足要求。

十三、策略模式的适用与不适用的场景

策略模式适用于那些需要根据不同情况使用不同算法或行为的场景。例如,当有多种排序算法可供选择时,或者当系统需要支持多种支付方式时,策略模式都是很好的选择。然而,对于那些算法或行为相对固定,不需要频繁更改的场景,使用策略模式可能会增加不必要的复杂性。

十四、代码示例扩展

在之前的示例中,我们演示了如何使用策略模式实现支付功能。现在,我们可以进一步扩展这个示例,加入更多具体的策略实现,如第三方支付策略、分期付款策略等。同时,我们可以考虑在支付上下文类中添加更多的逻辑,如验证支付信息的有效性、处理支付异常等。

十五、策略模式的实际应用案例

以电商平台的促销活动为例,不同的促销活动可能需要不同的折扣策略或优惠策略。通过使用策略模式,我们可以为每种促销活动定义一个具体的策略类,并在活动开始时动态地选择并应用相应的策略。这样,当平台需要推出新的促销活动或调整现有活动的策略时,只需添加或修改相应的策略类即可,无需修改整个促销系统的代码。

十六、策略模式的改进与扩展

在实际应用中,我们可以对策略模式进行改进和扩展,以满足更复杂的需求。例如,我们可以引入策略链模式,使得多个策略可以按照一定的顺序依次执行。此外,我们还可以考虑使用上下文映射来管理策略与上下文之间的关联关系,以便更方便地进行策略的选择和切换。

十七、策略模式的挑战与解决方案

虽然策略模式带来了很多好处,但在实际应用中也可能会遇到一些挑战。例如,当策略数量众多且复杂时,管理和维护这些策略可能会变得困难。为了解决这个问题,我们可以采用一些策略管理的最佳实践,如使用配置文件或数据库来存储和管理策略信息,或者开发专门的策略管理工具来简化策略的管理过程。

十八、策略模式的学习建议

学习策略模式时,建议从理解其基本概念和结构开始,然后通过编写简单的示例代码来加深理解。在掌握了基本用法后,可以尝试在实际项目中应用策略模式,并思考如何与其他设计模式结合使用来构建更健壮和灵活的系统。同时,也可以阅读一些关于策略模式的优秀文章和书籍,以获取更多的学习资源和灵感。

十九、策略模式的未来发展趋势

随着软件技术的不断发展和业务场景的不断变化,策略模式将继续发挥重要作用。未来,我们可以期待策略模式在更多领域得到应用,并与新的技术趋势和设计模式相结合,为构建更高效、更灵活的软件系统提供支持。

二十、总结与展望

策略模式是一种强大而灵活的设计模式,它允许我们在运行时动态地改变对象的行为。通过深入理解和掌握策略模式的概念、结构、实现方式以及优缺点,我们可以更好地应用它来解决实际问题并提升系统的可维护性和可扩展性。随着技术的不断进步和业务需求的不断变化,我们有理由相信策略模式将在未来继续发挥重要作用,并与其他设计模式和技术趋势共同推动软件行业的发展。

相关文章:

【设计模式】Java 设计模式之模板策略模式(Strategy)

策略模式详解:模式结构、实现与应用场景 一、策略模式概述 策略模式是一种行为设计模式,它使得算法可以独立于使用它的客户端变化。策略模式使得算法可以在运行时切换,从而增强了系统的灵活性和可维护性。在策略模式中,我们定义…...

SpringBoot项目前端Vue访问后端(图片静态资源) 配置

静态资源配置 Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {Value("${file.save-path}")private String fileSavePath;Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {//映射本地文件夹registry…...

colab中数据集保存到drive与取出的方法

from google.colab import drive drive.mount(/content/drive) 一、下载数据集 from datasets import load_dataset max_length 32 # Maximum length of the captions in tokens coco_dataset_ratio 50 # 50% of the COCO2014 dataset# Load the COCO2014 dataset for tr…...

React 应该如何学习?

学习 React 是现代 Web 前端开发中的重要一步,因为它是一个流行且强大的 JavaScript 库,用于构建用户界面。React 的学习过程需要掌握一系列的概念、技术和最佳实践。 1. 基础知识 1.1 HTML、CSS 和 JavaScript React 本质上是一个 JavaScript 库&…...

跨平台无缝操作:ShareMouse让多电脑协同更高效

ShareMouse是一款功能强大的鼠标和键盘共享软件,它支持多台计算机之间的无缝连接,让用户能够通过一套键鼠设备轻松控制多台电脑,提高工作效率。此外,ShareMouse还具备剪贴板共享、文件拖放等功能,实现不同计算机间的便…...

Vue使用pandoc-wasm进行各格式转换

前端使用pandoc-wasm的问题和建议 docx转md npm install --save pandoc-wasmimport { Pandoc } from "pandoc-wasm";const pandoc new Pandoc()pandoc.init().then(async (pandoc) > {const result await pandoc.run({text: "Some input text",opti…...

springboot284基于HTML5的问卷调查系统的设计与实现

问卷调查系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,问卷信息因为其管理内容繁杂,管理数量繁多导…...

AI短视频制作一本通:文本生成视频、图片生成视频、视频生成视频

第一部分:文本生成视频 1. 文本生成视频概述 随着人工智能(AI)技术的飞速发展,视频制作领域也迎来了创新的浪潮。文本生成视频是其中的一项令人激动的进展,它利用自然语言处理技术将文本内容转化为视频。这项技术在广…...

详谈分布式事务

目录 前言 1.sharding的分布式事务 2.分布式事务的产生原因 3.分布式事务的解决方案 3.1.DTP模型 3.2.分阶段提交 3.3.TCC模式 3.4.可靠消息服务 3.5.AT模式 3.6.Seata 前言 本文是前面一篇文章聊了基于sharding的分库分表后拓展出来的关于分布式事务的讨论&#xf…...

Java基础知识八股

1.为什么静态方法无法调用非静态方法? 回答:因为静态方法是随着类的加载而加载,而非静态方法则是随着类的实例化才会被加载,生存周期不一样,所以静态方法的生命周期更长 2.Java–内部类持有外部类导致内存泄露的原因和…...

【Linux】网络基础一

网络基础一 1.计算机网络背景1.1 网络发展1.2 认识 “协议” 2.网络协议初识2.1 协议分层2.2 OSI七层模型2.3 TCP/IP五层(或四层)模型 3. 网络传输基本流程3.1 网络传输流程图 4.数据包封装和分用5.网络中的地址管理 从今天开始我们将要从系统横跨到网络的学习了,因…...

Redis-2 Redis基础数据类型与基本使用

高级Redis应用进阶 一站式Redis解决方案-Redis-2 Redis基础数据类型与基本使用 源代码在GitHub - 629y/food-social-contact-parent: redis项目-美食社交APP 1. Redis基本数据类型 1.字符串(strings) set username zhangsan get username mset age 18 …...

python提取身份证中的生日和性别

1.代码 def sfzAnalysis(idNum):#检查身份证长度是否正确if len(idNum)!18:raise ValueError("身份证号码长度不正确,请输入一个18位的身份证号码。")#raise关键字在Python中有多种用途,主要涉及异常的抛出和错误处理#提取出生日期year idN…...

opencv 傅里叶变换(低通滤波 + 高通滤波)

文章目录 1、傅里叶变换2、通过numpy实现3、高通滤波器5、通过opencv实现傅里叶变换6、低通滤波器7、C实现傅里叶变换 1、傅里叶变换 时域分析:以时间作为参照物,世间万物都是随着时间变化而变化,并且不会停止 频域分析:认为世间万…...

Educational Codeforces Round 163 (Rated for Div. 2)(A,B,C,D,E)

比赛链接 好忙好忙好忙,慢慢补老比赛的题解了。 这场没啥算法,全是思维。有也是BFS,屎。 A. Special Characters 题意: 您将得到一个整数 n n n 。 您的任务是构建一串大写的拉丁字母。此字符串中必须正好有 n n n 个特殊字…...

索引常见面试题

面试中,MySQL 索引相关的问题基本都是一系列问题,都是先从索引的基本原理,再到索引的使用场景,比如: 索引底层使用了什么数据结构和算法?为什么 MySQL InnoDB 选择 Btree 作为索引的数据结构?什…...

【Unity】旋转的尽头是使用四元数让物体旋转

// 导入必要的命名空间 using System.Collections; using System.Collections.Generic; using UnityEngine;// 创建一个名为 RotateObj 的 MonoBehaviour 类,该类可以附加到 Unity 中的游戏对象上并控制其行为 public class RotateObj : MonoBehaviour {// Update 函…...

哔哩哔哩秋招Java二面

前言 作者:晓宜 个人简介:互联网大厂Java准入职,阿里云专家博主,csdn后端优质创作者,算法爱好者 一面过后面试官叫我别走,然后就直接二面,二面比较简短,记录一下,希望可以…...

OSPF特殊区域(stub\nssa)

stub区域——只有1类、2类、3类;完全stub区域——只有1类、2类 NSSA区域:本区域将自己引入的外部路由发布给其他区域,但不需要接收其他区域的路由 在NSSA区域的路由器上,引入外部路由时,不会转换成5类LSA&#xff0c…...

全球首位AI程序员诞生,将会对程序员的影响有多大?

随着全球首位AI程序员Devin的诞生,人工智能技术在编程领域的应用引发了广泛的讨论和思考。这一事件不仅标志着AI技术在软件开发领域的一大步进展,也引起了人们对未来编程职业发展的广泛关注。那么,AI程序员的出现究竟会对程序员的职业生涯产生…...

ARM地址转换与分支记录缓冲区(BRB)机制详解

1. ARM地址转换机制深度解析在ARMv8/ARMv9架构中,地址转换是内存管理单元(MMU)的核心功能,它通过多级页表将虚拟地址(VA)转换为物理地址(PA)。这种转换机制不仅实现了内存隔离和保护,还为虚拟化提供了硬件支持。我们先从最基础的地址转换指令…...

R 4.5 IoT聚合配置已过时?2024年TSDB联邦查询新规下,3种向后兼容迁移路径限时披露

第一章:R 4.5 物联网数据聚合配置R 4.5 版本引入了原生支持轻量级物联网设备数据流聚合的 iotagg 模块,专为边缘节点低内存环境优化。该模块通过时间窗口滑动与标签路由机制,实现毫秒级延迟的数据清洗、去重与多源对齐,无需依赖外…...

mfc140.dll文件丢失损坏怎么办? 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…...

新一代LoRA训练打标神器:支持多种打标风格,中英双语标签自由切换,打标效率飙升!

凡是经常训练 LoRA 的人都知道—— 给素材打标往往是决定模型质量的关键一步 标签质量的好坏,直接影响到最终 LoRA 模型的训练效果 而且不同的 LoRA 训练任务, 对标签的风格和语言表达要求也各不相同 如果完全依赖人工打标,不仅效率低下…...

如何用GSE宏工具彻底改变你的魔兽世界游戏体验

如何用GSE宏工具彻底改变你的魔兽世界游戏体验 【免费下载链接】GSE-Advanced-Macro-Compiler GSE is an alternative advanced macro editor and engine for World of Warcraft. 项目地址: https://gitcode.com/gh_mirrors/gs/GSE-Advanced-Macro-Compiler 还在为魔兽…...

MyBatis RowBounds分页踩坑实录:一次线上OOM事故教会我的事

MyBatis分页陷阱:从RowBounds内存泄漏到高效分页实战 凌晨三点,手机突然响起刺耳的报警声。打开监控系统一看,某核心服务的堆内存曲线像坐了火箭一样直线上升,最终触发了OOM崩溃。经过彻夜排查,罪魁祸首竟是项目中一段…...

用EasyX图形库给你的C语言课设加满分:从贪吃蛇到飞机大战的实战思路

用EasyX图形库为C语言课设注入视觉活力:从数据可视化到小游戏开发 每到期末,计算机专业的同学们总会面临一个共同的挑战:如何让C语言课设脱颖而出?当大多数同学还在使用控制台菜单交互时,掌握EasyX图形库就能让你的项目…...

科学家完成澳大利亚北部珊瑚礁海域地图绘制

澳大利亚北部海域发现逾千处此前从未被记录的珊瑚礁,科学家足不出户便完成了这一重大海洋生态系统的探测工作。此次项目由澳大利亚海洋科学研究所(AIMS)联合昆士兰大学共同主导,作为"海洋与海岸中心"项目的重要组成部分…...

别再死记硬背了!用Wireshark抓包,5分钟搞懂PPP链路IP地址协商(IPCP)全过程

用Wireshark透视PPP链路:IP地址协商全流程实战解析 第一次接触PPP链路的IP地址协商时,那些Config-Request、Config-Ack报文交互总让人云里雾里。直到我用Wireshark亲手抓取IPCP报文,才真正理解了为什么PPP链路两端的设备可以不在同一网段却依…...

Applera1n:iOS 15-16.6设备激活锁免费绕过完整指南

Applera1n:iOS 15-16.6设备激活锁免费绕过完整指南 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 如果你手头有一台带有激活锁的二手iPhone,看到那个熟悉的"Hello"界…...