【设计模式】策略模式(政策(Policy)模式)

策略模式(Strategy Pattern)详解


一、策略模式简介

策略模式(Strategy Pattern) 是一种 行为型设计模式(对象行为型模式),它定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换,独立于使用它们的客户端。

又称为政策(Policy)模式
每一个封装算法的类称之为策略(Strategy)类
策略模式提供了一种可插入式(Pluggable)算法的实现方案。

你可以把它理解为:

“一个工具箱里有多个工具,你可以在不同场景下选择不同的工具来完成任务。”

在策略模式中,这些“工具”就是各种具体的策略类,而“任务执行者”则是使用这些策略的对象。

旅游出行方式
在这里插入图片描述
实现某个目标的途径不止一条,可根据实际情况选择一条合适的途径。

软件开发
多种算法,例如排序、查找、打折等
使用硬编码(Hard Coding)实现将导致系统违背开闭原则,扩展性差,且维护困难
可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法 —> 策略类

public class Context
{……public void algorithm(String type)  {......if(type == "strategyA"){//算法A}else if(type == "strategyB"){//算法B}else if(type == "strategyC"){//算法C}......}……
} 

策略模式包含以下3个角色
Context(环境类)
Strategy(抽象策略类)
ConcreteStrategy(具体策略类)

在这里插入图片描述


二、解决的问题类型

策略模式主要用于解决以下问题:

  • 同一行为具有多种实现方式:比如支付方式可以是支付宝、微信、银行卡等。
  • 避免大量的 if-else 或 switch-case 判断逻辑:提高代码可读性和扩展性。
  • 希望在运行时动态切换算法或行为:比如根据用户等级选择不同的折扣策略。

三、使用场景

场景示例
不同支付方式支付宝、微信、银联等
折扣计算普通会员、VIP会员、超级会员等不同折扣规则
物流配送顺丰、京东、德邦等不同物流策略
游戏角色技能角色攻击方式随武器变化而变化

四、核心结构

策略模式通常包含三个部分:

  1. 策略接口(Strategy):定义所有策略共有的行为。
  2. 具体策略类(Concrete Strategies):实现接口中的具体行为。
  3. 上下文类(Context):持有一个策略接口的引用,负责调用策略方法。

五、实际代码案例(Java)

我们以电商系统中的“支付方式”为例,演示策略模式的使用。

1. 定义策略接口

// 支付策略接口
public interface PaymentStrategy {void pay(int amount);
}

2. 实现具体策略类

// 微信支付策略
public class WeChatPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("WeChat Pay: $" + amount);}
}// 支付宝支付策略
public class AliPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("AliPay: $" + amount);}
}// 银行卡支付策略
public class BankCardPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Bank Card Pay: $" + amount);}
}

3. 创建上下文类

// 上下文类:支付环境
public class ShoppingCart {private PaymentStrategy paymentStrategy;// 设置策略public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 使用策略进行支付public void checkout(int amount) {if (paymentStrategy == null) {throw new IllegalStateException("Please select a payment strategy.");}paymentStrategy.pay(amount);}
}

4. 客户端测试类

public class Client {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用微信支付cart.setPaymentStrategy(new WeChatPay());cart.checkout(100);// 切换为支付宝支付cart.setPaymentStrategy(new AliPay());cart.checkout(200);// 切换为银行卡支付cart.setPaymentStrategy(new BankCardPay());cart.checkout(300);}
}

输出结果:

WeChat Pay: $100
AliPay: $200
Bank Card Pay: $300

典型代码(C++)

典型的抽象策略类代码

abstract class AbstractStrategy
{public abstract void Algorithm(); //声明抽象算法
}

典型的抽象策略类代码

class ConcreteStrategyA : AbstractStrategy 
{
//算法的具体实现
public override void Algorithm() 
{//算法A
}
}

典型的环境类代码

class Context
{private AbstractStrategy strategy; //维持一个对抽象策略类的引用public void SetStrategy(AbstractStrategy strategy) {this.strategy = strategy;}//调用策略类中的算法public void Algorithm() {strategy.Algorithm();}
}

典型的客户端代码片段

……
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA(); //可在运行时指定类型,通过配置文件和反射机制实现
context.SetStrategy(strategy);
context.Algorithm();
……
其他案例
  1. 某软件公司为某电影院开发了一套影院售票系统,在该系统中需要为不同类型的用户提供不同的电影票打折方式,具体打折方案如下:
    (1) 学生凭学生证可享受票价8折优惠。
    (2) 年龄在10周岁及以下的儿童可享受每张票减免10元的优惠(原始票价需大于等于20元)。
    (3) 影院VIP用户除享受票价半价优惠外还可进行积分,积分累计到一定额度可换取电影院赠送的奖品。
    该系统在将来可能还要根据需要引入新的打折方式。现使用策略模式设计该影院售票系统的打折方案

在这里插入图片描述

  1. 排序策略
    某系统提供了一个用于对数组数据进行操作的类,该类封装了对数组的常见操作,如查找数组元素、对数组元素进行排序等。现以排序操作为例,使用策略模式设计该数组操作类,使得客户端可以动态地更换排序算法,可以根据需要选择冒泡排序或选择排序或插入排序,也能够灵活地增加新的排序算法。

在这里插入图片描述

  1. 旅游出行策略
    旅游出行方式可以有多种,如可以乘坐飞机旅游,也可以乘火车旅游,如果有兴趣自行车游也是一种极具乐趣的出行方式。不同的旅游出行方式有不同的实现过程,客户根据自己的需要选择一种合适的旅游方式。在本实例中我们用策略模式来模拟这一过程。

在这里插入图片描述

六、优缺点分析

优点描述
解耦将算法和使用它的对象分离,降低耦合度
易于扩展新增策略只需新增类,符合开闭原则。提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为
运行时可切换策略提供更高的灵活性
减少冗长的条件判断语句替代 if-else 或 switch-case 结构
其他提供了管理相关的算法族的办法,提供了一种可以替换继承关系的办法,提供了一种算法的复用机制,不同的环境类可以方便地复用策略类
缺点描述
增加类数量每个策略对应一个类,可能导致类膨胀,将造成系统产生很多具体策略类
需要对外暴露策略类客户端需了解所有策略才能选择使用哪个
不适合简单分支逻辑如果策略种类很少,使用策略模式反而增加了复杂度
其他无法同时在客户端使用多个策略类

七、与其他模式对比(补充)

模式名称目标
模板方法模式在父类定义算法骨架,子类实现具体步骤
责任链模式请求在链上传递,每个节点决定是否处理请求
策略模式多种算法/行为封装成策略,运行时可切换

八、最终小结

策略模式是一种非常实用的设计模式,适用于那些具有多种实现方式、需要灵活切换的业务逻辑。它通过将行为抽象为接口和实现类,使得程序更加清晰、易维护、易扩展。

在开发电商系统、支付模块、权限控制、游戏逻辑等项目中,策略模式都能发挥重要作用。


📌 一句话总结:

策略模式就像“万能遥控器”,可以自由切换不同的功能模块,让程序更灵活、更具适应性。


推荐使用方式:

  • 对于固定的行为,但实现方式多样的场景优先考虑策略模式;
  • 可结合工厂模式统一创建策略实例,提升管理效率;
  • 使用 Lambda 表达式简化简单策略的实现(如 Java 8+);

部分内容由AI大模型生成,注意识别!

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

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

相关文章

用TensorFlow进行逻辑回归(二)

逻辑回归的例子 逻辑回归是经典的分类算法。为了简单,我们考虑二分类。这意味着,我们要处理识别二个分类的问题,我们的标签为 0 或 1。 我们要一个与线性回归不同的激活函数,不同的损失函数,神经元的输出略有不同。我们…

Java设计模式之行为型模式(命令模式)介绍与说明

一、核心定义与目标 命令模式通过对象化请求,将操作的具体实现细节隐藏在命令对象中,使得调用者(Invoker)无需直接与接收者(Receiver)交互,仅需通过命令对象间接调用。这种解耦设计支持以下功能…

【深度学习新浪潮】xAI新发布的Grok4有什么看点?

Grok4作为马斯克旗下xAI公司最新发布的旗舰AI模型,其核心看点和评测要点可总结如下: 一、Grok4的核心看点 学术推理能力全面超越人类博士水平 在「人类终极考试」(HLE)中,Grok4基础版正确率达25.4%,启用工具后飙升至44.4%,远超Gemini 2.5 Pro(21.6%)和OpenAI o3(20.…

观成科技:基于自监督学习技术的恶意加密流量检测方案

1.前言当前,随着加密协议技术的广泛应用,互联网用户的个人流量隐私得到了有效保护,但与此同时也衍生出一系列安全问题。由于加密流量在传输过程中无法被解密,导致传输信息呈现“黑盒化”特征,这为恶意攻击者利用加密流…

通用定时器GPT

目录 GPT核心特性 GPT 计数器操作模式 重启模式 自由运行模式 GPT时钟源 GPT框图 输入捕获:测量外部信号的高电平脉冲宽度 输出比较:生成 1kHz PWM 波 GPT模块外部引脚复用与功能映射表 GPT使用注意事项 GPT Memory Map GPT寄存器 GPTx_CR寄存…

#oda0095. 字符串通配符【B卷 100分】-字符串

题目描述问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。要求:实现如下2个通配符:* :匹配0个或以上的字符(注&…

面向对象设计原则

面向对象:是一种编程思想,面向过程是关注实现的步骤,每个步骤定义一个函数,调用函数执行即可。面向对象关注的是谁来执行,把具有相同属性和行为的一类事物进行抽象成类,然后再通过实例化出一个个具体的对象…

Hyperledger Fabric深入解读:企业级区块链的架构、应用与未来

一、引言:企业级区块链的标杆Hyperledger Fabric是Linux基金会主导的开源项目,专为企业级应用设计,以模块化架构、许可链机制和隐私保护为核心,广泛应用于金融、供应链、医疗等领域。相较于公有链(如以太坊&#xff09…

从0开始学习R语言--Day45--Hausman检验

当我们在探究数据本身是否和变量相关时,往往都会对这两者进行回归分析,控制一下变量来看看趋势走向。但其实在分析前,我们可以先尝试做Hausman检验,这可以帮助我们判断数据的变化到底是因为变量不一样了还是因为自己的个体效应所以…

闲庭信步使用图像验证平台加速FPGA的开发:第九课——图像插值的FPGA实现

(本系列只需要modelsim即可完成数字图像的处理,每个工程都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真,大大降低了初学者的门槛!!!!如需要该系列的工程…

Android事件分发机制完整总结

一、核心概念事件分发的本质Android事件分发采用责任链模式,事件从Activity开始,依次经过ViewGroup和View。整个机制只有一个入口:dispatchTouchEvent方法。onInterceptTouchEvent和onTouchEvent都不是独立的事件入口,而是被dispa…

【论文阅读】AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking

AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking3. AdaReasoner3.1 动机3.2 问题定义3.3 动作选择过程3.3.1 动作空间定义3.3.2 动作选择3.4 探索策略3.5 强化学习训练3.5.1 训练算法3.5.2 目标函数3.5.3 损失函数AdaReasoner: Adaptive Reasoning Enables Mo…

深入了解Modbus TCP:工业通信的“通用语言”

目录 简介一、Modbus TCP的“前世今生”二、Modbus TCP的核心特点三、Modbus TCP的工作原理1. 报文结构2. 功能码四、Modbus TCP的应用场景五、使用Modbus TCP的注意事项六、总结简介 在工业自动化的世界里,不同设备之间的“对话”至关重要。从PLC(可编程逻辑控制器)到传感…

基于Selenium和FFmpeg的全平台短视频自动化发布系统

一、项目背景与概述在当今短视频营销盛行的时代,许多企业和个人需要同时管理多个短视频平台账号。手动上传视频到抖音、快手、小红书等平台不仅效率低下,而且容易出错。本文将介绍一个基于Python的自动化短视频处理与发布系统,它能够&#xf…

技术演进中的开发沉思-31 MFC系列:类层次结构

提及MFC,不得不说他的类层次。如果把 MFC 框架比作是座精密的钟表,那类层次结构便是其内部咬合的齿轮组。每个类都有明确的 “家族地位”,既继承着先辈的本领,又发展出独特的专长。这种层级分明的设计,让 Windows 编程…

2023.05.06 更新前端面试问题总结(12道题)

2023.05.04 - 2023.05.06 更新前端面试问题总结(12道题) 获取更多面试相关问题可以访问 github 地址: https://github.com/pro-collection/interview-question/issues gitee 地址: https://gitee.com/yanleweb/interview-question/issues 目录&#xff1…

【网络】Linux 内核优化实战 - net.ipv4.tcp_keepalive_intvl

目录1. TCP Keep-Alive 机制回顾2. 参数作用3. 参数取值与影响4. 使用场景与建议5. 相关参数6. 如何配置该参数临时生效(重启后失效):永久生效(需重启或重载配置):7. 性能优化建议8. 监控与故障排查net.ipv…

20250710解决KickPi的K7的SDK编译异常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】

20250710解决KickPi的K7的SDK编译异常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】 2025/7/10 20:59缘起:KickPi的K7的SDK编译异常:rk3576-android14.0-25250704.tar.gzZ:\14TB\SDK\rk3576_data\1-SDK软件源码\Android14\20250704…

《Java EE与中间件》实验一 基于MyBatis的留言本

目 录 一、实验目的和要求 1、实验目的 2、实验要求 二、实验实现思路及步骤 1、实验思路 2、实验步骤 3、实验方案 三、主要开发工具 四、实验效果及实现代码 1、留言本数据库构建实现 (1)建立javaee-project数据库 (2&#xf…

ARM汇编编程(AArch64架构) - 第14课:安全扩展(ARM TrustZone)

目录1. TrustZone基础概念1.1 安全扩展架构1.2 关键组件2. 世界切换机制2.1 状态切换流程2.2 关键寄存器配置3. SMC调用实现3.1 调用规范3.2 完整调用流程4. 实战练习4.1 实验:实现双世界通信4.2 调试技巧1. TrustZone基础概念 1.1 安全扩展架构 startuml rectang…