Java 编程之策略模式详解

一、策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,它将一组算法或行为封装成独立的类,使它们可以在运行时互相替换。

这让你在使用它们时,无需关心内部实现,只要"调度策略"即可。

外卖平台下单时,你可以选择专送、自取、商家送,每种方式都是不同的策略,但送达的目的相同。


二、举例说明

外卖的"配送方式"就是策略!在美团 / 饿了么平台点外卖时,配送方式多种多样:

  • 骑手专送:平台调度骑手
  • 商家自送:由商家安排送货
  • 自取:用户自己去拿

这些方式结构不同、流程不同,但都完成一件事------送达订单

这就非常符合策略模式的核心思想:一组互换的算法 / 行为,独立封装,灵活切换


三、代码实现

3.1. 策略接口

java 复制代码
// 配送策略接口
public interface DeliveryStrategy {
    void deliver(String orderId);
}

解释

每种配送方式都得遵守"deliver(订单)"这个协议,无论内部如何送。


3.2. 具体实现

java 复制代码
public class RiderDelivery implements DeliveryStrategy {
    @Override
    public void deliver(String orderId) {
        System.out.println("订单 " + orderId + " 由平台骑手专送");
    }
}

public class MerchantDelivery implements DeliveryStrategy {
    @Override
    public void deliver(String orderId) {
        System.out.println("订单 " + orderId + " 商家自行配送");
    }
}

public class SelfPickup implements DeliveryStrategy {
    @Override
    public void deliver(String orderId) {
        System.out.println("订单 " + orderId + " 用户到店自取");
    }
}

解释

每个策略对应一种配送方式,具体送法不同,但结构统一。


3.3. 上下文类

java 复制代码
public class OrderContext {
    private DeliveryStrategy strategy;

    public void setStrategy(DeliveryStrategy strategy) {
        this.strategy = strategy;
    }

    public void processOrder(String orderId) {
        if (strategy == null) {
            throw new IllegalStateException("未设置配送策略");
        }
        strategy.deliver(orderId);
    }
}

解释

外卖系统的订单上下文,可以按需设置当前的配送方式并执行。


3.4. 使用示例

用户选择配送方式

java 复制代码
public class Main {
    public static void main(String[] args) {
        OrderContext context = new OrderContext();

        context.setStrategy(new RiderDelivery());
        context.processOrder("10086");

        context.setStrategy(new MerchantDelivery());
        context.processOrder("10087");

        context.setStrategy(new SelfPickup());
        context.processOrder("10088");
    }
}

输出:

复制代码
订单 10086 由平台骑手专送  
订单 10087 商家自行配送  
订单 10088 用户到店自取  

四、策略模式结构图(UML)

plantuml 复制代码
@startuml
interface DeliveryStrategy {
  +deliver(orderId)
}

class RiderDelivery implements DeliveryStrategy
class SelfPickup implements DeliveryStrategy
class MerchantDelivery implements DeliveryStrategy

class OrderContext {
  - strategy: DeliveryStrategy
  + setStrategy(DeliveryStrategy)
  + processOrder(orderId)
}

DeliveryStrategy <|.. RiderDelivery
DeliveryStrategy <|.. SelfPickup
DeliveryStrategy <|.. MerchantDelivery
OrderContext --> DeliveryStrategy
@enduml

核心关系:

  • 所有策略实现 DeliveryStrategy
  • OrderContext 中组合一个策略对象,并调用其 deliver 方法

五、策略模式优点总结

优点 描述
解耦行为 将行为与上下文分离,低耦合高内聚
易于扩展 新增策略无需改动上下文
替代 if-else 取代多分支逻辑,结构清晰
满足开闭原则 封闭修改,开放扩展

"行为可插拔,运行可替换,逻辑高解耦。"

------ 不动主程序,只换策略模块,系统稳定又灵活。

六、实际使用场景

策略模式在很多业务中都有应用:

  • 支付方式:微信 / 支付宝 / 银行卡
  • 认证方式:密码登录 / 验证码登录 / 三方授权
  • 推荐算法:基于标签 / 基于历史 / 基于兴趣图谱
  • 缓存策略:本地优先 / 远程优先 / 混合缓存

七、升级写法:Java 8 Lambda 版(简洁优雅)

策略接口只有一个方法?可以用 Java 8 Lambda 简写!

java 复制代码
OrderContext context = new OrderContext();
context.setStrategy(orderId -> System.out.println("极速达配送:" + orderId));
context.processOrder("10100");

八、策略模式 vs 状态模式 区别一图解

比较点 策略模式 状态模式
意图 算法互换 状态驱动行为
控制者 外部设置策略 内部自动切换
行为绑定 手动设置 状态迁移
示例 支付策略 订单状态变更

九、参考

《23种设计模式概览》

相关推荐
带刺的坐椅44 分钟前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·ai·llm·solon·rag·chatmodel
用户3721574261352 小时前
Java 将 Word 文档转换为 Markdown:基础转换与导出选项详解
java
行者全栈架构师3 小时前
PolarDB + Spring Boot 实战:从自建MySQL到云原生数据库的零停机迁移
java·后端·架构
karry_k19 小时前
MyBatis批量insert-select踩坑:useGeneratedKeys=true 可能让PostgreSQL返回大量插入结果
java·后端
karry_k19 小时前
PostgreSQL 在 MyBatis 中执行正常 SQL 失效:一次 DELETE USING 踩坑记录
java·后端
SamDeepThinking1 天前
从源码到代码:MyBatis-Flex 与 MyBatis-Plus 的逐项对比
java·后端·程序员
她的男孩1 天前
Spring Boot 接 Flowable 工作流:用 3 个注解搭一个请假审批流程
java·后端·架构
荣码1 天前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
plainGeekDev1 天前
Gson → kotlinx.serialization
android·java·kotlin