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

《设计模式》策略模式

1.策略模式定义

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一组算法,将每个算法封装起来,并使它们可以相互替换,从而让算法的变化独立于使用它的客户(Client)。

换句话说, 策略模式让一个类的行为或其算法可以在运行时更改,而不会影响使用该类的代码。

UML图:

在这里插入图片描述

2.策略模式举例:

业务场景:需要实现一个商场收银系统,有三种策略,

  1. 正常结账
  2. 打折
  3. 满减
    实现业务功能如下:

2.1 代码设计UML图如下:

在这里插入图片描述

2.2 关键代码:

CashContext代码:和抽象工厂结合,减少耦合。之前客户端需要了解CashContext和CashSuper两个类,现在只需要了解CashContext一个类,封装更好,耦合更小。

public class CashContext {private CashSuper cs;   //声明一个CashSuper对象//通过构造方法,传入具体的收费策略public CashContext(int cashType){switch(cashType){case 1:this.cs = new CashNormal();break;case 2:this.cs = new CashRebate(0.8d);break;case 3:this.cs = new CashRebate(0.7d);break;case 4:this.cs = new CashReturn(300d,100d);break;}}public double getResult(double price,int num){//根据收费策略的不同,获得计算结果return this.cs.acceptCash(price,num);}    
}

CashSuper:


public abstract class CashSuper {public abstract double acceptCash(double price,int num);
}

CashReturn:

public class CashReturn extends CashSuper {private double moneyCondition = 0d; //返利条件private double moneyReturn = 0d;    //返利值//返利收费。初始化时需要输入返利条件和返利值。//比如“满300返100”,就是moneyCondition=300,moneyReturn=100public CashReturn(double moneyCondition,double moneyReturn){this.moneyCondition = moneyCondition;this.moneyReturn = moneyReturn;}//计算收费时,当达到返利条件,就原价减去返利值public double acceptCash(double price,int num){double result = price * num;if (moneyCondition>0 && result >= moneyCondition)result = result - Math.floor(result / moneyCondition) * moneyReturn; return result;}}

客户端代码:

public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("策略模式和简单工厂模式");System.out.println();		int discount = 0; 		//商品折扣模式(1.正常收费 2.打八折 3.打七折)double price = 0d; 		//商品单价int num = 0;			//商品购买数量double totalPrices = 0d;//当前商品合计费用double total = 0d;		//总计所有商品费用Scanner sc = new Scanner(System.in);do {System.out.println("请输入商品折扣模式(1.正常收费 2.打八折 3.打七折 4.满300送100):");	discount = Integer.parseInt(sc.nextLine());System.out.println("请输入商品单价:");	price = Double.parseDouble(sc.nextLine());System.out.println("请输入商品数量:");	num = Integer.parseInt(sc.nextLine());System.out.println();	if (price>0 && num>0){//根据用户输入,将对应的策略对象作为参数传入CashContext对象中CashContext cc = new CashContext(discount);//通过Context的getResult方法的调用,可以得到收取费用的结果//让具体算法与客户进行了隔离totalPrices = cc.getResult(price,num);total = total + totalPrices;System.out.println();	System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元");	System.out.println();System.out.println("总计:"+ total+"元");	System.out.println();}}while(price>0 && num>0);System.out.println();System.out.println("**********************************************");}
}

具体运行结果如下:
在这里插入图片描述

3.策略模式优缺点

✅ 优点

  • 符合开闭原则(Open-Closed Principle):可以新增新的策略,而不影响已有代码。
  • 避免冗长的 if-else 语句:如果不使用策略模式,可能会有大量 if-else 逻辑判断。
  • 支持动态切换:可以在运行时自由更换不同的算法,而不修改原有代码。
  • 代码更符合SOLID原则
设计原则策略模式如何符合
单一职责原则(SRP)每个 Strategy 只负责一个算法,职责清晰。
开闭原则(OCP)可以新增策略,而不修改原代码。
依赖倒置原则(DIP)Context 依赖于 Strategy 接口,而不是具体实现。

❌ 缺点

  • 增加了代码复杂度:每个策略都需要定义一个类,当策略过多时,会导致类爆炸。
  • 客户端需要了解不同策略:调用方需要知道有哪些可用策略,才能正确选择。

4.策略模式的应用场景

✅ (1) 算法的可替换性

计算税收(不同国家税率)
支付方式(微信支付、支付宝、银行卡)

✅ (2) 处理不同格式的文件

解析 JSON、XML、CSV 文件时,使用不同的解析策略。

✅ (3) AI/机器学习中的优化策略

训练模型时,可以使用不同的优化算法(SGD、Adam、RMSprop)。

5.策略模式 vs 其他模式

设计模式作用适用场景
策略模式允许在运行时更换不同算法当有多种算法可选,且希望避免 if-else 逻辑。
状态模式允许对象在不同状态下表现出不同行为对象的行为依赖于状态变化,例如订单状态。
工厂模式负责创建对象,但不指定其具体实现需要动态创建不同策略对象时,可结合策略模式使用。

6.总结

策略模式核心思想: 定义一组算法,让它们可以互相替换,而不会影响客户端代码。
适用于: 需要多个可替换算法,并希望避免 if-else 逻辑的场景。
优点: 符合开闭原则,可动态切换策略,避免冗长 if-else
缺点: 可能会增加类的数量,使代码更复杂。

7.参考引用

  • https://juejin.cn/post/7485322373614813220
http://www.dtcms.com/a/324291.html

相关文章:

  • STM32的计数模式和pwm模式
  • 亚麻云之数据安家——RDS数据库服务入门
  • sqli-labs-master/Less-62~Less-65
  • 01.【面试题】在SpringBoot中如何实现多数据源配置
  • (Python)爬虫进阶(Python爬虫教程)(CSS选择器)
  • 2025年全国青少年信息素养大赛Scratch编程践挑战赛-小低组-初赛-模拟题
  • Linux系统编程Day11 -- 进程状态的优先级和特性
  • 移动端音频处理实践:59MB变声应用的技术实现分析
  • 机器学习-增加样本、精确率与召回率
  • LeetCode 869.重新排序得到 2 的幂:哈希表+排序(一次初始化)
  • Android 16 KB页面大小适配的权威技术方案总结
  • Android快速视频解码抽帧FFmpegMediaMetadataRetriever,Kotlin(2)
  • Android 开发问题:Invalid id; ID definitions must be of the form @+id/ name
  • 010601抓包工具及证书安装-基础入门-网络安全
  • 浅谈 A2A SDK 核心组件
  • 电脑本地摄像头做成rtsp流调用测试windows系统中
  • 【Docker实战】将Django应用容器化的完整指南
  • Pytorch深度学习框架实战教程-番外篇10-PyTorch中的nn.Linear详解
  • Linux-静态配置ip地址
  • 怎么将视频转换成字幕python作为工具
  • 计算机视觉(CV)——pytorch张量基本使用
  • 深入解析Java中的String、StringBuilder与StringBuffer:特性、区别与最佳实践
  • Gin 框架中的模板引擎使用指南
  • LeetCode 每日一题 2025/8/4-2025/8/10
  • mpv core_thread pipeline
  • c语言常见错误
  • MySQL 处理重复数据详细说明
  • ADK(Agent Development Kit)【2】调用流程详解
  • 智慧交通-道路积雪识别分割数据集labelme格式1985张2类别
  • python Flask简单图书管理 API