Skip to content
进阶

一句话答案

定义算法族封装为独立类使其可互换,消除 if-else;Spring 中用 Map<String,Strategy> 注入所有实现按 type 选择。

核心要点

策略模式定义一系列算法,将每个算法封装成独立的类,使它们可以互相替换。客户端通过组合和委托的方式使用不同的策略。

传统 if/else 写法(反面教材):

java
public class NotificationService {
    public void send(String type, String message) {
        if ("sms".equals(type)) {
            // 发短信逻辑...
        } else if ("email".equals(type)) {
            // 发邮件逻辑...
        } else if ("push".equals(type)) {
            // 发推送逻辑...
        } else if ("wechat".equals(type)) {
            // 发微信逻辑...
        }
        // 每新增一种方式就要改这个方法,违反开闭原则
    }
}

策略模式重构:

java
// 1. 定义策略接口
public interface NotifyStrategy {
    void send(String message);
}

// 2. 实现各种策略
@Component("sms")
public class SmsStrategy implements NotifyStrategy {
    public void send(String message) { /* 发短信 */ }
}
@Component("email")
public class EmailStrategy implements NotifyStrategy {
    public void send(String message) { /* 发邮件 */ }
}
@Component("push")
public class PushStrategy implements NotifyStrategy {
    public void send(String message) { /* 发推送 */ }
}

// 3. 策略工厂(Map 分发,彻底消除 if/else)
@Component
public class NotifyStrategyFactory {
    @Autowired
    private Map<String, NotifyStrategy> strategyMap; 
    // Spring 会自动注入:key=beanName, value=bean实例
    
    public NotifyStrategy getStrategy(String type) {
        NotifyStrategy strategy = strategyMap.get(type);
        if (strategy == null) throw new IllegalArgumentException("未知通知类型: " + type);
        return strategy;
    }
}

// 4. 使用
@Service
public class NotificationService {
    @Autowired
    private NotifyStrategyFactory factory;
    
    public void send(String type, String message) {
        factory.getStrategy(type).send(message); // 一行代码搞定
    }
}

策略模式 + Map/枚举分发的三板斧:

  1. 定义策略接口
  2. 每种算法实现一个策略类
  3. 用 Map(或枚举)做路由分发,消除 if/else

Java 中的策略模式实例:

  • Comparator —— 不同的比较策略传给 Collections.sort()
  • ThreadPoolExecutor 的拒绝策略 —— AbortPolicy/CallerRunsPolicy/DiscardPolicy
  • Spring Resource —— ClassPathResource/FileSystemResource/UrlResource
追问与易错

追问方向:

  • 策略模式怎么消除 if-else?(Map<type, Strategy> + 工厂选择)
  • 策略模式和工厂模式结合怎么用?(工厂创建具体策略实例)
  • 你项目中哪里用了策略模式?

易错点:

  • ❌ "每次新增策略都要改代码"——用 Spring 自动注入所有实现类到 Map 中
  • ❌ 混淆策略模式和状态模式——策略由客户端选择,状态由内部自动切换

💡 记忆锚点

导航App选路线:快速路、不走高速、少收费站,每条路线是一个策略类,你(客户端)选哪条走哪条。Spring三板斧:接口定义路线规则 → 每条路线一个实现类 → Map按名字查路线,彻底干掉if-else岔路口。