策略模式(Strategy Pattern)详解
一、策略模式简介
策略模式(Strategy Pattern) 是一种 行为型设计模式(对象行为型模式),它定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换,独立于使用它们的客户端。
又称为政策(Policy)模式 。
每一个封装算法的类称之为策略(Strategy)类 。
策略模式提供了一种可插入式(Pluggable)算法的实现方案。
你可以把它理解为:
"一个工具箱里有多个工具,你可以在不同场景下选择不同的工具来完成任务。"
在策略模式中,这些"工具"就是各种具体的策略类,而"任务执行者"则是使用这些策略的对象。
(旅游出行方式 )
实现某个目标的途径不止一条,可根据实际情况选择一条合适的途径。
软件开发 :
多种算法,例如排序、查找、打折等
使用硬编码(Hard Coding)实现将导致系统违背开闭原则,扩展性差,且维护困难
可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法 ---> 策略类
java
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会员、超级会员等不同折扣规则 |
物流配送 | 顺丰、京东、德邦等不同物流策略 |
游戏角色技能 | 角色攻击方式随武器变化而变化 |
四、核心结构
策略模式通常包含三个部分:
- 策略接口(Strategy):定义所有策略共有的行为。
- 具体策略类(Concrete Strategies):实现接口中的具体行为。
- 上下文类(Context):持有一个策略接口的引用,负责调用策略方法。
五、实际代码案例(Java)
我们以电商系统中的"支付方式"为例,演示策略模式的使用。
1. 定义策略接口
java
// 支付策略接口
public interface PaymentStrategy {
void pay(int amount);
}
2. 实现具体策略类
java
// 微信支付策略
public class WeChatPay implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("WeChat Pay: $" + amount);
}
}
// 支付宝支付策略
public class AliPay implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("AliPay: $" + amount);
}
}
// 银行卡支付策略
public class BankCardPay implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Bank Card Pay: $" + amount);
}
}
3. 创建上下文类
java
// 上下文类:支付环境
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. 客户端测试类
java
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++)
典型的抽象策略类代码
cpp
abstract class AbstractStrategy
{
public abstract void Algorithm(); //声明抽象算法
}
典型的抽象策略类代码
cpp
class ConcreteStrategyA : AbstractStrategy
{
//算法的具体实现
public override void Algorithm()
{
//算法A
}
}
典型的环境类代码
cpp
class Context
{
private AbstractStrategy strategy; //维持一个对抽象策略类的引用
public void SetStrategy(AbstractStrategy strategy)
{
this.strategy = strategy;
}
//调用策略类中的算法
public void Algorithm()
{
strategy.Algorithm();
}
}
典型的客户端代码片段
cpp
......
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA(); //可在运行时指定类型,通过配置文件和反射机制实现
context.SetStrategy(strategy);
context.Algorithm();
......
其他案例
- 某软件公司为某电影院开发了一套影院售票系统,在该系统中需要为不同类型的用户提供不同的电影票打折方式,具体打折方案如下:
(1) 学生凭学生证可享受票价8折优惠。
(2) 年龄在10周岁及以下的儿童可享受每张票减免10元的优惠(原始票价需大于等于20元)。
(3) 影院VIP用户除享受票价半价优惠外还可进行积分,积分累计到一定额度可换取电影院赠送的奖品。
该系统在将来可能还要根据需要引入新的打折方式。现使用策略模式设计该影院售票系统的打折方案

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

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

六、优缺点分析
优点 | 描述 |
---|---|
✅ 解耦 | 将算法和使用它的对象分离,降低耦合度 |
✅ 易于扩展 | 新增策略只需新增类,符合开闭原则。提供了对开闭原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为 |
✅ 运行时可切换策略 | 提供更高的灵活性 |
✅ 减少冗长的条件判断语句 | 替代 if-else 或 switch-case 结构 |
其他 | 提供了管理相关的算法族的办法,提供了一种可以替换继承关系的办法,提供了一种算法的复用机制,不同的环境类可以方便地复用策略类 |
缺点 | 描述 |
---|---|
❌ 增加类数量 | 每个策略对应一个类,可能导致类膨胀,将造成系统产生很多具体策略类 |
❌ 需要对外暴露策略类 | 客户端需了解所有策略才能选择使用哪个 |
❌ 不适合简单分支逻辑 | 如果策略种类很少,使用策略模式反而增加了复杂度 |
其他 | 无法同时在客户端使用多个策略类 |
七、与其他模式对比(补充)
模式名称 | 目标 |
---|---|
模板方法模式 | 在父类定义算法骨架,子类实现具体步骤 |
责任链模式 | 请求在链上传递,每个节点决定是否处理请求 |
策略模式 | 多种算法/行为封装成策略,运行时可切换 |
八、最终小结
策略模式是一种非常实用的设计模式,适用于那些具有多种实现方式、需要灵活切换的业务逻辑。它通过将行为抽象为接口和实现类,使得程序更加清晰、易维护、易扩展。
在开发电商系统、支付模块、权限控制、游戏逻辑等项目中,策略模式都能发挥重要作用。
📌 一句话总结:
策略模式就像"万能遥控器",可以自由切换不同的功能模块,让程序更灵活、更具适应性。
✅ 推荐使用方式:
- 对于固定的行为,但实现方式多样的场景优先考虑策略模式;
- 可结合工厂模式统一创建策略实例,提升管理效率;
- 使用 Lambda 表达式简化简单策略的实现(如 Java 8+);
部分内容由AI大模型生成,注意识别!