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

【设计模式】策略模式(政策(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.dtcms.com/a/277830.html

相关文章:

  • pycharm+SSH 深度学习项目 远程后台运行命令
  • AI生成单词消消乐游戏. HTML代码
  • hercules zos 安裝 jdk 8
  • 【读书笔记】《C++ Software Design》第十章与第十一章 The Singleton Pattern The Last Guideline
  • MyBatis04-MyBatis小技巧
  • 【读书笔记】《Effective Modern C++》第六章 Lambda Expressions
  • Spring AI多模态API初体验:文字、图片、语音,一个接口全搞定!
  • 【研报复现】开源证券:均线的收敛与发散
  • DevOps
  • 深度学习图像分类数据集—玉米粒质量识别分类
  • 设计模式之单例模式:深入解析全局唯一对象的艺术
  • JVM 锁自动升级机制详解
  • 哈希扩展 --- 布隆过滤器
  • 肿瘤浸润淋巴细胞是什么,与三级淋巴结构的关系
  • 会计 - 22 - 外币折算
  • Linux713 SAMBA;磁盘管理:手动挂载,开机自动挂载,自动挂载
  • 补:《每日AI-人工智能-编程日报》--2025年7月12日
  • CTFSHOW pwn161 WP
  • 如何成为 PostgreSQL 中级专家
  • 论文学习_SemDiff: Binary Similarity Detection by Diffing Key-Semantics Graphs
  • 4G PPP模式与以太网接口在LwIP中的融合应用
  • JAVA AI智能体——1 入门
  • Redis 基础详细介绍(Redis简单介绍,命令行客户端,Redis 命令,Java客户端)
  • day5--上传视频
  • AI赋能ERP:从自动化到智能化,企业运营的未来已来
  • 【SpringBoot】注册条件+自动配置原理+自定义starter
  • 每天学习一个Python第三方库之jieba库
  • 【DVWA系列】——File Upload——low详细教程(webshell工具冰蝎)
  • on-policy和offpolicy算法
  • 计算机时钟演进:从毫秒到纳秒的精密革命