【设计模式】策略模式(Strategy)详解:把 if-else 变成可切换的算法

文章目录

    • [1. 引言:if-else 正在失控](#1. 引言:if-else 正在失控)
    • [2. 什么是策略模式](#2. 什么是策略模式)
      • [GoF 定义](#GoF 定义)
    • [3. 策略模式的核心思想](#3. 策略模式的核心思想)
    • [4. 策略模式的结构](#4. 策略模式的结构)
    • [5. 示例:商品价格计算](#5. 示例:商品价格计算)
      • [5.1 策略接口](#5.1 策略接口)
      • [5.2 具体策略](#5.2 具体策略)
      • [5.3 上下文](#5.3 上下文)
      • [5.4 客户端使用](#5.4 客户端使用)
    • [6. 策略模式的优点](#6. 策略模式的优点)
    • [7. 策略模式的缺点](#7. 策略模式的缺点)
    • [8. 策略 vs 模板方法](#8. 策略 vs 模板方法)
    • [9. JDK 中的策略模式](#9. JDK 中的策略模式)
    • [10. 适用场景](#10. 适用场景)
    • [11. 一个常见误区](#11. 一个常见误区)
    • 参考

1. 引言:if-else 正在失控

在实际项目中,你很可能见过这样的代码:

java 复制代码
public double calculate(double price, String type) {
    if ("VIP".equals(type)) {
        return price * 0.8;
    } else if ("SVIP".equals(type)) {
        return price * 0.6;
    } else if ("NORMAL".equals(type)) {
        return price;
    }
    return price;
}

问题非常明显:

  • if-else 越来越长
  • 新规则要改老代码
  • 违反开闭原则

当条件分支开始膨胀时,策略模式就是最优解。有选择,就有策略。


2. 什么是策略模式

GoF 定义

定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。

详解:策略模式模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

一句话理解:

把算法当成对象来用。


3. 策略模式的核心思想

策略模式的本质是:

  • 行为抽象
  • 算法解耦
  • 运行期切换

它强调:

用组合代替条件判断。


4. 策略模式的结构

策略模式包含三个角色:

  1. Strategy(策略接口)类

这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  1. ConcreteStrategy(具体策略)类

实现了抽象策略定义的接口,提供具体的算法实现或行为。

  1. Context(上下文)

持有一个策略类的引用,最终给客户端调用。


5. 示例:商品价格计算

5.1 策略接口

java 复制代码
public interface PriceStrategy {
    double calculate(double price);
}

5.2 具体策略

java 复制代码
public class NormalPriceStrategy implements PriceStrategy {
    public double calculate(double price) {
        return price;
    }
}
java 复制代码
public class VipPriceStrategy implements PriceStrategy {
    public double calculate(double price) {
        return price * 0.8;
    }
}
java 复制代码
public class SvipPriceStrategy implements PriceStrategy {
    public double calculate(double price) {
        return price * 0.6;
    }
}

5.3 上下文

java 复制代码
public class PriceContext {

    private PriceStrategy strategy;

    public PriceContext(PriceStrategy strategy) {
        this.strategy = strategy;
    }

    public double getFinalPrice(double price) {
        return strategy.calculate(price);
    }
}

5.4 客户端使用

java 复制代码
PriceContext context = new PriceContext(new VipPriceStrategy());
System.out.println(context.getFinalPrice(100));

运行时随意切换算法。


6. 策略模式的优点

  1. 消除 if-else
  2. 算法可自由扩展
  3. 符合开闭原则
  4. 运行期灵活切换

7. 策略模式的缺点

  1. 类数量增加
  2. 客户端需理解策略
  3. 策略选择逻辑需额外管理

8. 策略 vs 模板方法

维度 策略模式 模板方法
技术手段 组合 继承
切换方式 运行期 编译期
灵活性

9. JDK 中的策略模式

Comparator

java 复制代码
Collections.sort(list, comparator);

排序算法不变,比较规则可切换。


10. 适用场景

  • 规则引擎
  • 支付策略
  • 排序算法
  • 风控策略

11. 一个常见误区

策略模式不是为了"多写类",而是为了"少写条件判断"。


参考

策略模式 | 菜鸟教程

《图解设计模式》

策略 - Java教程 - 廖雪峰的官方网站

策略设计模式

相关推荐
代码改变生活-1202 小时前
idea 清除缓存之后重启项目编译失败
java·缓存·intellij-idea
老蒋每日coding2 小时前
AI智能体设计模式系列(二)—— 路由模式
人工智能·设计模式
Microsoft Word2 小时前
HashMap面试题总结
java·开发语言
stillaliveQEJ2 小时前
【MyBatis】DML映射
java·mybatis
qq_12498707532 小时前
基于SSM框架的智能密室逃脱信息管理系统(源码+论文+部署+安装)
java·大数据·人工智能·spring boot·后端·毕业设计·计算机毕业设计
ekkcole2 小时前
java实现对excel文件合并单元格(只针对文件)
java·开发语言·excel
no24544102 小时前
RAGFlow 全面接入 MinerU 2.0,支持 pipeline、vlm-transformers、vlm-sglang 三种模式,解析精度大幅度up
java·大数据·人工智能·python·ai·sglang
lkbhua莱克瓦242 小时前
MySQL事务隔离级别:从并发混乱到数据一致性守护者
java·数据库·mysql·隔离级别