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

【设计模式】-策略模式:优雅处理条件逻辑

Java 策略模式之优雅处理条件逻辑

前言

在软件开发中,我们经常会遇到根据不同的条件执行不同逻辑的情况。这时,策略模式是一种常用的设计模式,能够使代码结构清晰、易于扩展和维护。

本文将详细介绍策略模式的概念及其在Java中的应用,通过代码示例演示如何使用策略模式来处理条件逻辑,以达到代码设计的灵活性和可维护性。

什么是策略模式?

策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时根据不同的条件选择不同的算法或行为。它将每个条件分支的逻辑封装在一个独立的类中,使得它们可以独立变化,互不影响。

策略模式使用了面向对象的封装、继承和多态等特性,使得代码具备高内聚低耦合的特点。通过将条件逻辑的变化封装到策略类中,不仅可以简化代码的编写,还能提高代码的可维护性、可扩展性和可重用性。

实现原理

策略模式实现原理主要涉及以下几个部分:

  1. 策略接口(Strategy Interface):定义了各个策略类必须实现的方法。这个接口将算法逻辑进行抽象,并定义了统一的方法或行为。

  2. 策略类(Concrete Strategies)实现(implements)策略接口,并封装了具体的算法逻辑。每个具体策略类都是独立的且具体逻辑互相隔离,分别实现不同的算法。

  3. 上下文类(Context):包含一个策略接口成员变量,并在运行时根据需要使用具体的策略类。上下文类通过策略接口与具体的策略类进行交互,并调用策略类中定义的算法。上下文主要用于决定使用哪个策略类

使用策略模式的关键在于上下文类与策略类之间的耦合解耦。上下文类通过策略接口具体的策略类进行交互,而不是直接依赖于具体的策略类。这样,在需要更换或增加新的策略时,只需要修改上下文类的代码,而不需要修改客户端的代码,从而实现了代码的灵活性和可扩展性。

示例:支付系统中的策略模式

假设我们正在开发一个支付系统,其中有多种支付方式,包括现金支付、信用卡支付和支付宝支付。不同的支付方式计算价格的逻辑可能有所不同,我们可以使用策略模式来实现这一需求。

首先,我们定义一个策略接口PaymentStrategy,它声明了一个名为calculatePrice的方法用于计算价格:

1.定义策略接口

// 定义策略接口
public interface PaymentStrategy {double calculatePrice(double price);
}

2.定义策略类,实现PaymentStrategy接口的方法:

// 策略类:使用现金支付
public class CashPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 这里是现金支付的价格计算逻辑return price * 0.9; // 打9折}
}// 策略类:使用信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 这里是信用卡支付的价格计算逻辑return price * 1.2; // 加收20%手续费}
}// 策略类:使用支付宝支付
public class AlipayPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 这里是支付宝支付的价格计算逻辑return price * 0.95; // 打95折}
}

3.接下来,我们创建一个上下文类PaymentContext,用于将不同的策略类进行封装,外部调用时只需关注该上下文类:

// 上下文类
public class PaymentContext {private PaymentStrategy paymentStrategy;public PaymentContext(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public double calculate(double price) {return paymentStrategy.calculatePrice(price);}
}

4.最后,我们可以通过实例化不同的策略类对象,并将其传入PaymentContext中,然后调用calculate方法进行价格计算:

public class Main {public static void main(String[] args) {PaymentStrategy cashPayment = new CashPaymentStrategy();PaymentContext cashPaymentContext = new PaymentContext(cashPayment);double cashPrice = cashPaymentContext.calculate(100.0);System.out.println("现金支付价格:" + cashPrice);PaymentStrategy creditCardPayment = new CreditCardPaymentStrategy();PaymentContext creditCardPaymentContext = new PaymentContext(creditCardPayment);double creditCardPrice = creditCardPaymentContext.calculate(100.0);System.out.println("信用卡支付价格:" + creditCardPrice);PaymentStrategy alipayPayment = new AlipayPaymentStrategy();PaymentContext alipayPaymentContext = new PaymentContext(alipayPayment);double alipayPrice = alipayPaymentContext.calculate(100.0);System.out.println("支付宝支付价格:" + alipayPrice);}
}

运行上述代码可以得到如下输出:

现金支付价格:90.0
信用卡支付价格:120.0
支付宝支付价格:95.0

在以上示例中,我们定义了三种不同的支付策略:现金支付信用卡支付支付宝支付,它们分别实现了PaymentStrategy接口并实现了自己的价格计算逻辑。通过创建PaymentContext对象并传入不同的支付策略,我们可以调用calculate方法获得相应的价格结果。

总结

        通过策略模式,我们可以优雅地处理条件逻辑,将各个条件分支的逻辑封装到独立的策略类中,使得代码结构清晰、易于扩展和维护。

        策略模式适用于需求中存在多个条件分支,并且这些条件分支的逻辑会随时变化的情况。使用策略模式能够提高代码的可读性和可维护性,同时也符合面向对象设计原则中的开闭原则。

        在实际开发中,我们可以根据具体需求灵活运用策略模式,帮助我们构建出高质量、易于维护的代码。

参考资料:

  • 《Head First 设计模式》

相关文章:

【设计模式】-策略模式:优雅处理条件逻辑

Java 策略模式之优雅处理条件逻辑 前言 在软件开发中,我们经常会遇到根据不同的条件执行不同逻辑的情况。这时,策略模式是一种常用的设计模式,能够使代码结构清晰、易于扩展和维护。 本文将详细介绍策略模式的概念及其在Java中的应用&#x…...

SpringBoot整合多数据源

SpringBoot整合多数据源 在实际企业项目开发中,我们经常会在SpringBoot项目中配置多数据源,一方面可以减缓数据库压力,另一方面可以也是业务需求的场景 下面就来看看如何在SpringBoot项目中配置多数据源 POM 在配置多数据源之前&#xff…...

CLIP论文精度

CLIP论文精度 Zero-shot CLIP多模态模型 Image Endecoder是一个图片编码器,既可以是ResNet,也可以是Vision Transformer. Text Encoder和Image Encoder产生的两组特征进行对比学习(无监督训练) 分类头?“分类头” 是指网络结…...

LouvainMethod分布式运行的升级之路

1、背景介绍 Louvain是大规模图谱的谱聚类算法,引入模块度的概念分二阶段进行聚类,直到收敛为止。分布式的代码可以在如下网址进行下载。 GitHub - Sotera/spark-distributed-louvain-modularity: Spark / graphX implementation of the distri…...

【Node.js】低代码平台源码

一、低代码简介 低代码管理系统是一种通过可视化界面和简化的开发工具,使非专业开发人员能够快速构建和管理应用程序的系统。它提供了一套预先定义的组件和模块,使用户可以通过拖放操作来设计应用程序的界面和逻辑。低代码管理系统还提供了自动化的工作…...

docker 部署 xxl-job-admin

1、先安装mysql docker pull mysql 2、运行mysql 容器 ( 端口 3306 容器名称 mysql 密码 123456 ) docker run -d --name mysql -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 mysql 3、将tables_xxl_job.sql文件(官网地址:http…...

c++(空间配置器)[32]

空间配置器 一级空间配置器 || 二级空间配置器 默认先走二级然后判断 二级空间配置器 一个指针指向start_free然后start_free向后移动,相当于哈希桶的头删和头插 8byte:切大补小 C的二级空间配置器按照8字节(或者更大的倍数)切分…...

Linux系列之解压文件

一.欢迎来到我的酒馆 使用命令解压Linux文件。 目录 一.欢迎来到我的酒馆二.使用命令解压文件 二.使用命令解压文件 2.1解压 .tar.gz文件: tar -zxvf 文件名.tar.gz.tar,gz这种文件是tar文件的压缩文件,因此可以使用tar命令进行解压 -zxvf命令参数&…...

为什么重写equals方法时必须重写hashcode方法

与 equals的区别 如果两个引用类型变量使用运算符,那么比较的是地址,它们分别指向的是否是同一地址的对象,结果一定是false,因为两个对象地址必然不同。 不能实现比较对象的值是否相同。 所有对象都有equals方法,默认…...

java导入excel图片处理

直接看代码吧,主要逻辑吧excel的图片拿到 压缩上传获取url // 将文件转成XSSFWorkbook工作簿XSSFWorkbook wb new XSSFWorkbook(uploadFile);// 获取工作薄中第一个excel表格XSSFSheet sheet wb.getSheetAt(0);// 核心:::获取ex…...

【Rust】Rust学习 第四章认识所有权

第四章认识所有权 所有权(系统)是 Rust 最为与众不同的特性,它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全。因此,理解 Rust 中所有权如何工作是十分重要的。 4.1 所有权 所有运行的程序都…...

学习C语言第三天 :关系操作符、逻辑操作符

1.关系操作符 C语言用于比较的表达式&#xff0c;称为“关系表达式”里面使用的运算符就称(relationalexpression)&#xff0c;为“关系运算符” (relationaloperator) &#xff0c;主要有下面6个。 > 大于运算符 < 小于运算符 > 大于等于运算符 < 小于等…...

Jenkins自动化打包脚本

一、背景 jenkins可以设置定时任务打包&#xff0c;也已手动点按钮打包&#xff0c;还可以通过执行http请求打包&#xff0c;今天我们就通过shell脚本&#xff0c;通过curl命令进行jenkins打包。 二、步骤 2.1 在jenkins上构建项目 设置触发器 2.2 通过shell脚本触发远程构…...

一百五十、Kettle——Kettle官网下载地址

一、官网地址 Home - Hitachi VantaraThe site home pagehttps://community.hitachivantara.com/docs/DOC-1009855 二、下载地址 Pentaho from Hitachi Vantara download | SourceForge.netDownload Pentaho from Hitachi Vantara for free. End to end data integration and…...

使用 Visual Studio Code 调试 CMake 脚本

之前被引入到 Visual Studio 中的 CMake 调试器&#xff0c;现已在 Visual Studio Code 中可用。 也就是说&#xff0c;现在你可以通过在 VS Code 中安装 CMake 工具扩展&#xff0c;来调试你的 CMakeLists.txt 脚本了。是不是很棒? 背景知识 Visual C 开发团队和 CMake 的维…...

【云原生】Docker 详解(二):Docker 架构及工作原理

Docker 详解&#xff08;二&#xff09;&#xff1a;Docker 架构及工作原理 Docker 在运行时分为 Docker 引擎&#xff08;服务端守护进程&#xff09; 和 客户端工具&#xff0c;我们日常使用各种 docker 命令&#xff0c;其实就是在使用 客户端工具 与 Docker 引擎 进行交互。…...

微服务 云原生:基于 Gogs + Drone 实现 CI/CD 自动化

一般构建部署 以一个简单的前后端项目来说&#xff0c;分别编写前后端的 Dockerfile 文件并构建镜像&#xff0c;然后编写 docker-compose.yml 构建部署&#xff0c;启动运行。每次代码变更后都需重新手动打包、构建、推送。 一个简单的例子&#xff1a; 前端&#xff1a; 项…...

ADO.NET之SQL Server

ADO.NET是.NET平台上的一组用于访问和操作关系型数据库的API。它提供了一种以统一的方式连接到各种数据库系统并执行数据库操作的方法。现在有很多的ORM框架都是基于ADO.NET进行数据访问&#xff08;比如&#xff1a;Entity Framework (EF)、Dapper、NHibernate 、FluentNHiber…...

Nginx负载均衡(重点)

正向代理 部署正向代理 server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; proxy_pass http://20.0.0.60:80…...

第一章 SpringBoot入门

1.SpringBoot简介 1.1.简介 Spring Boot来简化spring应用开发&#xff0c;约定大于配置去繁从简&#xff0c;just run就能创建一个独立的&#xff0c;产品级别的应用。 背景&#xff1a;J2EE笨重开发&#xff0c;繁多的配置、低下开发效率、复杂的部署流程、第三方技…...

Qwen3-TTS-Tokenizer-12Hz生产环境应用:高并发音频编解码服务架构

Qwen3-TTS-Tokenizer-12Hz生产环境应用&#xff1a;高并发音频编解码服务架构 1. 引言&#xff1a;音频编解码的技术挑战与解决方案 在现代语音应用中&#xff0c;音频数据的处理和传输一直是个头疼的问题。你想啊&#xff0c;一段普通的语音文件&#xff0c;动辄就是几MB甚至…...

基于PySide6的YOLO通用检测平台:从零搭建与多场景适配

1. PySide6与YOLO的强强联合 PySide6作为Qt官方提供的Python绑定库&#xff0c;让开发者能够用Python快速构建跨平台的图形界面应用。而YOLO作为当前最流行的实时目标检测算法&#xff0c;在工业质检、安防监控、医疗影像等领域都有广泛应用。将两者结合&#xff0c;可以打造出…...

攻克表情显示难题:Noto Emoji企业级解决方案

攻克表情显示难题&#xff1a;Noto Emoji企业级解决方案 【免费下载链接】noto-emoji Noto Emoji fonts 项目地址: https://gitcode.com/gh_mirrors/no/noto-emoji 当你精心设计的聊天应用在用户手机上显示为"□□"乱码&#xff0c;当跨国团队的沟通因表情差异…...

论文阅读:arxiv 2026 From Assistant to Double Agent: Formalizing and Benchmarking Attacks on OpenClaw for

总目录 大模型安全研究论文整理 2026年版&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/159047894 From Assistant to Double Agent: Formalizing and Benchmarking Attacks on OpenClaw for Personalized Local AI Agent https://arxiv.org/abs/2602.08412 该…...

打造 AI 冒险团:HagiCode 多 Agent 协作配置实战派

MySQL 中的 count 三兄弟&#xff1a;效率大比拼&#xff01; 一、快速结论&#xff08;先看结论再看分析&#xff09; 方式 作用 效率 一句话总结 count(*) 统计所有行数 最高 我是专业的&#xff01;我为统计而生 count(1) 统计所有行数 同样高效 我是 count(*) 的马甲兄弟…...

从雅可比矩阵到概率重塑:标准化流如何成为生成式模型的精确解?

1. 标准化流&#xff1a;生成式模型的精确解 想象你手里有一张白纸&#xff0c;上面画着一个标准圆形。现在你想把它变成一幅复杂的山水画&#xff0c;但又希望每一步修改都能精确追踪——这就是标准化流&#xff08;Normalizing Flows&#xff09;在概率分布世界做的事情。与其…...

为机械臂视觉抓取铺路:在ROS Melodic环境下,一步步配置YOLOv5的Python和PyTorch依赖

为机械臂视觉抓取铺路&#xff1a;在ROS Melodic环境下配置YOLOv5的Python和PyTorch依赖 机械臂视觉抓取是当前工业自动化和机器人研究的热点领域&#xff0c;而YOLOv5作为目标检测的利器&#xff0c;能够为机械臂提供精准的物体定位信息。但在实际部署中&#xff0c;开发者常…...

Qwen3.5-9B高效编码:OpenClaw自动补全Python函数

Qwen3.5-9B高效编码&#xff1a;OpenClaw自动补全Python函数 1. 为什么需要AI代码补全&#xff1f; 作为一个长期与Python打交道的开发者&#xff0c;我经常陷入这样的困境&#xff1a;在深夜赶项目时&#xff0c;明明知道要实现什么功能&#xff0c;却卡在具体函数实现的细节…...

专业数据恢复师工具箱揭秘:UFS Explorer Pro的5个高级功能实战解析

专业数据恢复师工具箱揭秘&#xff1a;UFS Explorer Pro的5个高级功能实战解析 当一块硬盘的文件系统彻底崩溃&#xff0c;分区表不知所踪&#xff0c;或是RAID阵列的配置信息丢失时&#xff0c;普通数据恢复软件往往束手无策。这正是UFS Explorer Professional Recovery展现其…...

深度学习_YOLO,卡尔曼滤波和

1.YOLO 1.1 简介 YOLO系列算法是一类典型的one-stage目标检测算法&#xff0c;其利用anchor box将分类与目标定位的回归问题结合起来&#xff0c;从而做到了高效、灵活和泛化性能好&#xff0c;所以在工业界也十分受欢迎. Yolo算法采用一个单独的CNN模型实现end-to-end的目标检…...