策略模式简介

策略模式是一种行为型设计模式,核心思想是把一系列算法封装成独立的类,让它们可以互相替换。调用方只依赖抽象接口,压根不用关心具体用哪个算法。代码里满屏的 if-else、switch-case来选算法?用策略模式一拆,每个分支变成一个策略类,调用方想用哪个就注入哪个,干干净净。策略模式有3个角色:

  1. Strategy策略接口,定义算法的抽象方法

  2. ConcreteStrategy 具体策略,实现不同的算法逻辑

3)Context上下文,持有策略接口引用,把实际工作委托给策略对象

java 复制代码
// 策略接口
interface PayStrategy {
    void pay(int amount);
}

// 具体策略:微信支付
class WeChatPay implements PayStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("微信支付 " + amount + " 元");
    }
}

// 具体策略:支付宝
class AliPay implements PayStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("支付宝支付 " + amount + " 元");
    }
}

// 上下文
class PayContext {
    private PayStrategy strategy;

    public void setStrategy(PayStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(int amount) {
        strategy.pay(amount);
    }
}

// 使用
PayContext context = new PayContext();
context.setStrategy(new WeChatPay());
context.executePayment(100);  // 微信支付 100 元

context.setStrategy(new AliPay());
context.executePayment(200);  // 支付宝支付 200 元

加一种新支付方式?新建一个策略类就行,Context代码一行不用动。常见使用场景:

1)支付系统,微信、支付宝、银联、Apple Pay,每种支付方式一个策略

2)促销活动,满减、打折、满赠、秒杀,不同促销规则用不同策略计算价格

3)数据导出,导出Excel、CSV、PDF,格式不同但接口统一

4)日志框架,输出到控制台、文件、远程服务器,Logback的Appender 就是策略模式

扩展知识

策略模式解决什么问题

假设没有策略模式,促销价格计算可能长这样:

java 复制代码
public double calculate(String type, double price) {
    if ("满减".equals(type)) {
        return price >= 100 ? price - 20 : price;
    } else if ("折扣".equals(type)) {
        return price * 0.8;
    } else if ("秒杀".equals(type)) {
        return 9.9;
    }
    // 每加一种促销,这里就多一个分支
    return price;
}

问题很明显:促销类型越多,这个方法越臃肿。改一种促销逻辑,整个方法都有风险。测试也麻烦,想单独测某种促销逻辑,得把整个方法跑一遍。

策略模式把每种促销拆成独立的类,各自演化互不影响,单元测试也能单独跑。

策略的选择谁来负责

策略模式把算法封装好了,但具体用哪个策略还得有人决定。常见做法有3种:

实际项目里工厂模式配合策略模式最常见,搞一个Map 把策略类型和策略对象映射起来:

java 复制代码
@Component
public class PayStrategyFactory {
    @Autowired
    private Map<String, PayStrategy> strategyMap;

    public PayStrategy getStrategy(String type) {
        return strategyMap.get(type);
    }
}

Spring会自动把所有PayStrategy实现类注入到这个Map里,key是Bean名称。

相关推荐
笨拙的老猴子5 天前
小明学架构师的第七课:策略模式:告别if-else的选择困难症
系统架构·策略模式
肖爱Kun6 天前
C++设计策略模式
开发语言·c++·策略模式
折哥的程序人生 · 物流技术专研7 天前
Java 23 种设计模式:从踩坑到精通 | 番外:策略 vs 模板方法 —— 组合与继承的终极对决
java·策略模式·java面试·comparator·模版方法模式·java设计模式·从踩坑到精通
折哥的程序人生 · 物流技术专研7 天前
Java 23 种设计模式:从踩坑到精通 | 番外:状态 vs 策略 —— if-else 消除的两条路,你走对了吗?
java·spring·状态模式·策略模式·java面试·java设计模式·从踩坑到精通
ttod_qzstudio9 天前
【软考设计模式】策略模式:算法族的封装与动态切换精讲
设计模式·策略模式
儒雅的名10 天前
GoF设计模式——策略模式
设计模式·bash·策略模式
折哥的程序人生 · 物流技术专研11 天前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
在水一缸12 天前
拒绝被打扰:深度解析 macOS 进程守护与“反自动启动”攻防战
macos·策略模式·用户体验·进程守护·自动启动·系统权限
折哥的程序人生 · 物流技术专研12 天前
第3篇:手写促销策略引擎(满减、打折、立减)
java·设计模式·策略模式·开闭原则·编程实战·扩充系列·促销引擎
杨运交12 天前
[045][Crypto模块]设计一个可扩展的加解密框架:策略模式与工厂模式实战
linux·运维·策略模式