请解释Java中的策略模式,并举例说明其应用场景和实现方式。请解释Java中的模板方法模式,并讨论其在实际项目中的应用。
请解释Java中的策略模式,并举例说明其应用场景和实现方式。
策略模式(Strategy Pattern)
策略模式是一种行为设计模式,它使你能够定义一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。
应用场景
- 多种算法:当你有多种算法需要实现,并且这些算法可以互相替换时。
- 算法使用场景变化:当需要在运行时决定使用哪种算法时。
- 隐藏具体实现:客户端不需要知道它正在使用哪个具体的算法,只需要知道如何使用这个算法即可。
示例:支付系统
假设我们有一个在线购物系统,用户可以选择多种支付方式,如信用卡支付、微信支付、支付宝支付等。这些支付方式的处理逻辑各不相同,但对外提供的接口(如支付方法)是一致的。这时,我们可以使用策略模式来设计这个支付系统。
实现方式
-
定义策略接口:首先,我们定义一个支付策略的接口,该接口包含了一个支付方法。
public interface PaymentStrategy { | |
void pay(Order order); | |
} |
-
实现具体策略:然后,我们为每个支付方式实现一个具体的策略类。
public class CreditCardPaymentStrategy implements PaymentStrategy { | |
@Override | |
public void pay(Order order) { | |
// 信用卡支付逻辑 | |
} | |
} | |
public class WeChatPayStrategy implements PaymentStrategy { | |
@Override | |
public void pay(Order order) { | |
// 微信支付逻辑 | |
} | |
} | |
// 同样地,可以为支付宝支付等实现其他策略类 |
-
上下文(Context):接下来,我们创建一个上下文类,该类持有一个策略对象的引用,并提供一个设置策略对象的方法。客户端通过上下文类来调用策略方法。
public class PaymentContext { | |
private PaymentStrategy strategy; | |
public void setStrategy(PaymentStrategy strategy) { | |
this.strategy = strategy; | |
} | |
public void executePayment(Order order) { | |
if (strategy != null) { | |
strategy.pay(order); | |
} | |
} | |
} |
-
客户端使用:最后,在客户端代码中,我们可以根据需要选择不同的支付策略,并通过上下文类来执行支付操作。
public class Client { | |
public static void main(String[] args) { | |
PaymentContext context = new PaymentContext(); | |
// 假设用户选择信用卡支付 | |
context.setStrategy(new CreditCardPaymentStrategy()); | |
Order order = new Order(/* 订单信息 */); | |
context.executePayment(order); | |
// 如果用户改变支付方式,只需要更换策略对象即可 | |
// context.setStrategy(new WeChatPayStrategy()); | |
// context.executePayment(order); | |
} | |
} |
这样,我们就实现了一个基于策略模式的支付系统。当需要添加新的支付方式时,我们只需要实现一个新的策略类,并在客户端代码中设置这个新的策略对象即可,而不需要修改已有的代码。
请解释Java中的模板方法模式,并讨论其在实际项目中的应用。
模板方法模式(Template Method Pattern)
模板方法模式是一种行为设计模式,它在一个方法中定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
模板方法模式的结构
-
抽象类(Abstract Class):定义了一个或多个抽象操作作为算法的步骤,并定义了一个模板方法,这个模板方法调用了这些抽象操作。
-
具体子类(Concrete Subclasses):为抽象类中的抽象操作提供具体的实现。
模板方法模式的优点
- 代码复用:模板方法定义了算法的骨架,子类可以继承这些代码,避免重复编写。
- 扩展性好:当需要添加新的算法步骤时,只需在抽象类中增加新的抽象方法,并在模板方法中调用它,然后子类可以针对新的抽象方法提供具体的实现。
- 灵活性:子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
模板方法模式在实际项目中的应用
-
文件处理:在处理不同类型的文件(如文本文件、图片文件、视频文件等)时,可以使用模板方法模式。抽象类定义了文件处理的通用步骤(如打开文件、读取内容、处理内容、关闭文件),子类则针对不同类型的文件提供具体的实现(如文本文件的读取、图片文件的解码等)。
-
UI渲染:在图形用户界面(GUI)的渲染过程中,可以使用模板方法模式。抽象类定义了渲染的通用步骤(如初始化画布、绘制背景、绘制控件、处理用户输入等),子类则可以根据不同的UI风格或需求提供具体的实现。
-
数据库操作:在数据库操作中,增删改查(CRUD)通常有一系列的通用步骤(如建立连接、执行SQL语句、处理结果、关闭连接)。使用模板方法模式,可以将这些通用步骤定义在抽象类中,子类则针对不同类型的数据库或SQL语句提供具体的实现。
-
工作流程处理:在需要处理复杂工作流程的场景中,如订单处理、支付流程等,可以使用模板方法模式。抽象类定义了工作流程的通用步骤(如验证输入、执行核心操作、记录日志、发送通知等),子类则可以根据具体的业务规则或需求提供具体的实现。
示例代码以下是一个简单的模板方法模式示例,展示了文件处理的场景:
// 抽象类 | |
public abstract class FileProcessor { | |
// 模板方法 | |
public final void processFile(String fileName) { | |
openFile(fileName); | |
readFileContent(); | |
processContent(); | |
closeFile(); | |
} | |
// 抽象操作 | |
protected abstract void openFile(String fileName); | |
protected abstract void readFileContent(); | |
protected abstract void processContent(); | |
protected abstract void closeFile(); | |
} | |
// 具体子类 | |
public class TextFileProcessor extends FileProcessor { | |
// 为抽象操作提供具体实现 | |
@Override | |
protected void openFile(String fileName) { | |
// 打开文本文件的实现 | |
} | |
@Override | |
protected void readFileContent() { | |
// 读取文本文件内容的实现 | |
} | |
@Override | |
protected void processContent() { | |
// 处理文本文件内容的实现 | |
} | |
@Override | |
protected void closeFile() { | |
// 关闭文本文件的实现 | |
} | |
} |
在这个示例中,FileProcessor 是抽象类,定义了文件处理的通用步骤和抽象操作。TextFileProcessor 是具体子类,为这些抽象操作提供了针对文本文件的实现。客户端可以通过 TextFileProcessor 的实例来调用 processFile 方法,从而完成文本文件的处理。如果需要处理其他类型的文件,可以创建其他子类并提供相应的实现。
相关文章:
请解释Java中的策略模式,并举例说明其应用场景和实现方式。请解释Java中的模板方法模式,并讨论其在实际项目中的应用。
请解释Java中的策略模式,并举例说明其应用场景和实现方式。 策略模式(Strategy Pattern) 策略模式是一种行为设计模式,它使你能够定义一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使…...
Vim基础操作:常用命令、安装插件、在VS Code中使用Vim及解决Vim编辑键盘错乱
Vim模式 普通模式(Normal Mode): 这是 Vim 的默认模式,用于执行文本编辑命令,如复制、粘贴、删除等。在此模式下,你可以使用各种 Vim 命令来操作文本。插入模式(Insert Mode)&#…...
基于Windows API DialogBox的对话框
在C中,DialogBox函数是Windows API的一部分,它用于在Win32应用程序中创建并显示一个模态对话框。DialogBox函数是USER32.DLL中的一个导出函数,因此你需要在你的C Win32应用程序中链接到这个库。 #include "framework.h" #include …...
五十一、openlayers官网示例Layer Min/Max Resolution解析——设置图层最大分辨率,超过最大值换另一个图层显示
使用minResolution、maxResolution分辨率来设置图层显示最大分辨率。 <template><div class"box"><h1>Layer Min/Max Resolution</h1><div id"map" class"map"></div></div> </template><…...
24年计算机等级考试22个常见问题解答❗
24年9月计算机等级考试即将开始,整理了报名中容易遇到的22个问题,大家对照入座,避免遇到了不知道怎么办? 1、报名条件 2、报名入口 3、考生报名之后后悔了,不想考了,能否退费? 4、最多能够报多少…...
obsidian制作自己的主题一文入门
制作自己的主题 我最近发现一款插件,直接把obsidian的文章格式复制到公众号中。 我非常喜欢这个功能,这将减少公众号排版的时间,同时保持公众号文章格式的一致性。 但是这个插件提供的模板不能满足我的需求,所以,需要…...
游戏心理学Day20
扩展的8种玩家 完成主义者 此类玩家关心的是成就和进展,其主要目的是完成游戏的主要目标,其次是完成游戏的次要目标之后才是游戏中的其他内容,在多人游戏中完成主义者会致力于炫耀自己的状态和财富。如果游戏以胜负为目标,那么此…...
Serverless如何赋能餐饮行业数字化?乐凯撒思变之道
导语 | 在数字化浪潮席卷全球的今天,每一个行业都在经历着前所未有的变革。餐饮行业作为人们日常生活中不可或缺的一部分,更是面临着巨大的转型压力。如何完成数字化转型,打破传统经营模式的限制,成为摆在众多餐饮商家面前的一道难…...
css系列:音频播放效果-波纹律动
介绍 语音播放的律动效果,通俗来说就是一个带动画的特殊样式的进度条,播放的部分带有上下律动的动画,未播放的部分是普通的灰色竖状条。 实现中夹带了less变量、继承和循环遍历,可以顺带学习一下。 结果展示 大致效果如图所示…...
WPF学习(1)--类与类的继承
在面向对象编程中,继承是一种机制,允许一个类(称为子类或派生类)从另一个类(称为父类或基类)继承属性和方法。继承使我们能够创建一个通用类,然后根据需要扩展或修改它以创建更具体的类。以下是…...
Spring Boot框架的原理及应用详解(六)
本系列文章简介: 在当今的软件开发世界中,快速迭代、高效开发以及易于维护成为了开发者们不断追求的目标。Spring Boot作为Spring框架的一个子项目,自其诞生以来就凭借其“约定大于配置”的理念和自动配置的特性,迅速在Java开发社…...
密码学与信息安全面试题及参考答案(2万字长文)
目录 什么是密码学?它的主要目标是什么? 请解释明文、密文、加密和解密的概念。 密码系统的安全性通常基于哪三种假设? 什么是Kerckhoffs原则?它对现代密码学设计有何意义? 简述密码学中的“混淆”和“扩散”概念。 什么是AES(高级加密标准)?AES有几种常见的密钥…...
C++语法19 循环嵌套结构(for/while循环)
语法阶段已经更新到第18章了,前面的知识你都学会了吗?如果还没有学习前面的知识,请点击👉语法专栏进行学习哦! 目录 循环嵌套 训练:数字矩形 解析 参考代码 训练:星号三角形 解析 参考代码 …...
AtomicInteger原理和CAS与Synchronized(juc编程)
AtomicInteger原理 4.6.1 原理介绍 AtomicInteger的本质:自旋锁 CAS算法 CAS的全成是: Compare And Swap(比较再交换); 是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。CAS可以将read-modify-write转换为原子操作,这…...
抖音a_bogus,mstoken全参数爬虫逆向补环境2024-06-15最新版
抖音a_bogus,mstoken全参数爬虫逆向补环境2024-06-15最新版 接口及参数 打开网页版抖音,右键视频进入详情页。F12打开控制台筛选detail,然后刷新网页,找到请求。可以发现我们本次的参数目标a_bogus。a_bogus有时长度为168有时为172…...
【机器学习】机器学习重要方法—— 半监督学习:理论、算法与实践
文章目录 引言第一章 半监督学习的基本概念1.1 什么是半监督学习1.2 半监督学习的优势 第二章 半监督学习的核心算法2.1 自训练(Self-Training)2.2 协同训练(Co-Training)2.3 图半监督学习(Graph-Based Semi-Supervise…...
leetcode70 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例 2&#x…...
ENVI实战—一文搞定非监督分类
实验1:使用isodata法分类 目的:学会使用isodata法开展非监督分类 过程: ①导入影像:打开ENVI,按照“文件→打开为→光学传感器→ESA→Sentinel-2”的顺序,打开实验1下载的哨兵2号数据。 图1 ②区域裁剪…...
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt系统相关 | Qt事件 | 事件的介绍及基本概念 文章编号:Qt…...
具身智能特点及实现路线
多模态——多功能的“小脑” 人类具有眼耳鼻舌身意,说明对于物理世界的充分感知和理解,是意识和智慧的来源。而传统AI更多的是被动观测,主要是“看”(计算机视觉)和“读”(文本NLP),…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
