【设计模式】策略模式(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教程 - 廖雪峰的官方网站

策略设计模式

相关推荐
雨中飘荡的记忆9 小时前
ElasticJob分布式调度从入门到实战
java·后端
_哆啦A梦17 小时前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
考虑考虑17 小时前
JDK25模块导入声明
java·后端·java ee
_小马快跑_19 小时前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Re_zero21 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记21 小时前
Spring Boot条件注解详解
java·spring boot
程序员清风2 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5512 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊2 天前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing2 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员