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

策略设计模式

相关推荐
JAVA面经实录9176 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
许彰午8 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
Bat U8 小时前
JavaEE|多线程初阶(七)
java·开发语言
掌心向暖RPA自动化11 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭11 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev12 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
geovindu12 小时前
go: Strategy Pattern
开发语言·设计模式·golang·策略模式
AI人工智能+电脑小能手13 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试
likerhood13 小时前
SLF4J: Failed to load class “StaticLoggerBinder“ 解决
java·log4j·maven