聊一聊:设计模式——策略模式

134 阅读4分钟

你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了近百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞


策略模式详解


一、定义与核心思想

策略模式(Strategy Pattern) 是一种行为型设计模式,通过定义一系列算法族并使其可相互替换,让算法独立于使用它的客户端而变化。其核心在于封装变化点,将算法的选择与执行解耦,使得系统更灵活、易于扩展。


二、适用场景

  1. 多种算法变体:如支付方式(支付宝/微信/银联)、排序算法(快速排序/归并排序)。
  2. 运行时动态切换策略:如游戏角色根据装备切换攻击方式。
  3. 替代复杂条件分支:消除代码中大量的if-elseswitch-case
  4. 算法复用:多个类需要共享相同算法的不同实现。

三、模式结构

角色职责
策略接口(Strategy)定义算法族的公共接口(如PaymentStrategy)。
具体策略(Concrete Strategy)实现策略接口的具体算法(如AlipayStrategyWeChatPayStrategy)。
上下文(Context)持有策略引用,负责调用具体策略(如Order类)。

四、实现示例:支付策略选择

// 策略接口
public interface PaymentStrategy {
    void pay(double amount);
}

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

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

// 上下文:订单类
public class Order {
    private PaymentStrategy strategy;
    private double total;

    public Order(double total) {
        this.total = total;
    }

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment() {
        if (strategy != null) {
            strategy.pay(total);
        } else {
            throw new IllegalStateException("未选择支付方式");
        }
    }
}

// 客户端使用
Order order = new Order(100.0);
order.setPaymentStrategy(new AlipayStrategy()); // 动态切换策略
order.executePayment(); // 输出:支付宝支付:100.0元

order.setPaymentStrategy(new WeChatPayStrategy());
order.executePayment(); // 输出:微信支付:100.0元

五、核心优势

  1. 开闭原则:新增策略无需修改上下文代码。
  2. 消除条件分支:替代冗长的if-else逻辑,提升可维护性。
  3. 算法复用:不同上下文可共享同一策略实现。
  4. 运行时灵活性:动态切换策略,适应多变需求。

六、应用案例

  1. Java Comparator:通过传递不同Comparator实现定制排序规则。

    List<Integer> nums = Arrays.asList(3,1,4);
    nums.sort(Comparator.reverseOrder()); // 策略:逆序排序
    
  2. Spring ResourceLoader:根据资源前缀(classpath:http:)选择加载策略。

  3. 电商促销活动:满减、折扣、赠品等促销策略灵活组合。

  4. 游戏AI行为:NPC根据环境切换移动策略(巡逻/追击/逃跑)。


七、进阶技巧

1. 策略工厂优化
public class PaymentStrategyFactory {
    private static Map<String, PaymentStrategy> strategies = new HashMap<>();
    
    static {
        strategies.put("alipay", new AlipayStrategy());
        strategies.put("wechat", new WeChatPayStrategy());
    }
    
    public static PaymentStrategy getStrategy(String type) {
        return strategies.getOrDefault(type, () -> {
            throw new UnsupportedOperationException("不支持的支付类型");
        });
    }
}

// 使用
order.setPaymentStrategy(PaymentStrategyFactory.getStrategy("alipay"));
2. Lambda简化策略

Java 8+ 可使用函数式接口替代策略类:

public class Order {
    private Consumer<Double> paymentStrategy;
    
    public void setPaymentStrategy(Consumer<Double> strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void executePayment() {
        paymentStrategy.accept(total);
    }
}

// 客户端
order.setPaymentStrategy(amount -> System.out.println("信用卡支付:" + amount));

八、注意事项

  1. 策略类数量:过多策略可能导致类膨胀,可结合其他模式优化。
  2. 策略无状态:若策略需维护状态,需确保线程安全。
  3. 客户端感知策略:需权衡是否暴露策略选择逻辑给客户端。

九、与其他模式对比

模式核心差异
状态模式策略模式客户端主动选择策略;状态模式自动切换状态。
工厂模式工厂模式创建对象;策略模式管理算法实现。
模板方法模式模板方法在父类定义流程;策略模式完全替换算法。

十、总结

策略模式通过抽象算法实现动态绑定机制,为系统提供了高度灵活性和可维护性。其核心价值在于:

  • 解耦算法定义与使用,符合单一职责原则。
  • 支持快速扩展新策略,适应业务变化。
  • 提升代码可读性,消除复杂条件判断。

在需要灵活切换算法消除重复条件分支的场景中,策略模式是提升代码质量的利器。

今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师

qrcode_for_gh_79f35896a87f_258.jpg