深入设计模式之「策略模式」:行为封装与选择的利器

一、什么是策略模式?

策略模式(Strategy Pattern) 是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并且使它们可以互换。

策略模式让算法独立于使用它的客户端而变化,也就是“行为的选择权”交给了客户端。


二、为什么要使用策略模式?

✅ 场景痛点:行为选择分支难以维护

面对复杂的行为选择逻辑,我们经常写出如下代码:

if (user.isVip()) {
    discount = price * 0.8;
} else if (user.isMember()) {
    discount = price * 0.9;
} else {
    discount = price;
}

这种代码存在如下问题:

  • 条件判断耦合在一起:每次新增一种策略,需修改原有方法

  • 违反开闭原则:代码不易扩展

  • 测试难、复用性低:行为无法独立测试和复用

✅ 策略模式正是为了解决这类问题而设计:将每种策略抽离成独立类,使其可以互换、动态替换、灵活扩展。


✅ 类比说明:出行策略的选择

不同出行需求下,人们可能会选择:

  • 🚗 自驾:适合短途出行

  • 🚇 地铁:高峰时通勤利器

  • 🚖 打车:便捷但昂贵

这些“出行方式”就是可互换的“策略”,我们可以将它们封装为类,再根据实际情况动态选择最合适的一种。


三、策略模式结构

角色

职责说明

Context

上下文类,使用策略类并持有其引用

Strategy

抽象策略接口,定义统一的方法

ConcreteStrategy

具体策略类,实现特定的算法


四、Java 实现:电商平台折扣策略系统

✅ 1. 抽象策略接口

public interface DiscountStrategy {
    double applyDiscount(double price);
}


✅ 2. 具体策略类

原价策略

public class NoDiscountStrategy implements DiscountStrategy {
    public double applyDiscount(double price) {
        return price;
    }
}

会员 9 折策略

public class MemberDiscountStrategy implements DiscountStrategy {
    public double applyDiscount(double price) {
        return price * 0.9;
    }
}

VIP 8 折策略

public class VipDiscountStrategy implements DiscountStrategy {
    public double applyDiscount(double price) {
        return price * 0.8;
    }
}


✅ 3. 上下文类

public class PriceCalculator {
    private DiscountStrategy strategy;
    public PriceCalculator(DiscountStrategy strategy) {
        this.strategy = strategy;
    }
    public void setStrategy(DiscountStrategy strategy) {
        this.strategy = strategy;
    }
    public double calculate(double price) {
        return strategy.applyDiscount(price);
    }
}


✅ 4. 使用示例

public class Main {
    public static void main(String[] args) {
        PriceCalculator calculator = new PriceCalculator(new NoDiscountStrategy());
        System.out.println("原价:" + calculator.calculate(100));
        calculator.setStrategy(new MemberDiscountStrategy());
        System.out.println("会员价:" + calculator.calculate(100));
        calculator.setStrategy(new VipDiscountStrategy());
        System.out.println("VIP价:" + calculator.calculate(100));
    }
}


五、适用场景总结

应用场景

描述

存在多个可互换的行为算法

如不同打折、排序、验证算法

策略之间行为独立且可替换

可以灵活切换策略的场合

客户端需在运行时动态选择行为策略

用户配置、A/B 测试等


六、策略模式的优点

优点

说明

行为独立、职责单一

每种策略各自封装

满足开闭原则

添加新策略不需修改上下文

策略可动态切换

支持运行时更改策略

易于扩展和单元测试

策略类独立可复用


七、缺点及典型问题场景

缺点

问题描述

策略类数量激增

策略越多,类越多

客户端需了解所有策略

策略选择权交给客户端,增加负担

可能出现策略选择逻辑外泄

上下文以外决定策略时逻辑分散


❌ 场景 1:支付系统策略类激增

在一个国际支付平台中,每个国家 / 支付方式(支付宝、PayPal、微信、信用卡)都有独立计算手续费的策略。

随着业务扩展,策略类数量过多,难以管理。

✅ 解决方案:

  • 将策略类归类到包中(按支付渠道划分)

  • 使用注册中心 + 简单工厂动态配置策略


❌ 场景 2:客户端选择策略逻辑外泄

客户端需通过如下代码手动判断策略:

if (user.isVip()) {
    strategy = new VipDiscountStrategy();
}

✅ 解决方案:

  • 引入策略工厂封装选择逻辑

  • 或引入配置驱动策略选择(策略由外部配置注入)


八、扩展方向

扩展点

描述

策略注册中心

将策略注册到 Map 中,按 key 获取策略

与工厂模式结合使用

使用工厂动态创建策略实例

与配置文件集成

根据配置动态指定策略类名并实例化

与注解配合使用

结合 Spring 注解自动注入策略


九、总结

策略模式 是行为切换场景的优雅解法,适用于需要灵活扩展和切换算法的业务逻辑。

📌 适用前提

  • 多种行为算法可互换

  • 算法实现独立封装

  • 客户端需根据情况选择行为

📌 使用建议

  • 控制策略类数量,避免类爆炸

  • 使用策略工厂简化客户端策略选择

  • 尽量避免策略选择逻辑外泄

下一篇将带你深入讲解「模版方法模式」的核心思想与进阶用法 👨‍🏫

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小健学 Java

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值