Java策略模式详解

策略模式详解

一、模式定义

策略模式(Strategy Pattern)属于行为型模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。

二、核心结构

1. 抽象策略接口

复制代码
public interface Strategy {
    void executeAlgorithm();
}

2. 具体策略实现

复制代码
public class ConcreteStrategyA implements Strategy {
    public void executeAlgorithm() {
        System.out.println("执行策略A的算法逻辑");
        // 具体算法实现...
    }
}

public class ConcreteStrategyB implements Strategy {
    public void executeAlgorithm() {
        System.out.println("执行策略B的算法逻辑");
        // 具体算法实现...
    }
}

3. 上下文类

复制代码
public class Context {
    private Strategy strategy;
    
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public void executeStrategy() {
        strategy.executeAlgorithm();
    }
}

三、完整示例:电商促销系统

1. 促销策略接口

复制代码
public interface PromotionStrategy {
    double applyPromotion(double originalPrice);
}

2. 具体促销策略

复制代码
// 无促销
public class NoPromotion implements PromotionStrategy {
    public double applyPromotion(double originalPrice) {
        return originalPrice;
    }
}

// 折扣促销
public class DiscountPromotion implements PromotionStrategy {
    private double discountRate;
    
    public DiscountPromotion(double discountRate) {
        this.discountRate = discountRate;
    }
    
    public double applyPromotion(double originalPrice) {
        return originalPrice * discountRate;
    }
}

// 满减促销
public class FullReductionPromotion implements PromotionStrategy {
    private double fullAmount;
    private double reductionAmount;
    
    public FullReductionPromotion(double fullAmount, double reductionAmount) {
        this.fullAmount = fullAmount;
        this.reductionAmount = reductionAmount;
    }
    
    public double applyPromotion(double originalPrice) {
        return originalPrice >= fullAmount ? 
               originalPrice - reductionAmount : 
               originalPrice;
    }
}

3. 订单类(上下文)

复制代码
public class Order {
    private double amount;
    private PromotionStrategy promotionStrategy;
    
    public Order(double amount) {
        this.amount = amount;
        this.promotionStrategy = new NoPromotion();
    }
    
    public void setPromotionStrategy(PromotionStrategy strategy) {
        this.promotionStrategy = strategy;
    }
    
    public double calculateFinalPrice() {
        return promotionStrategy.applyPromotion(amount);
    }
}

4. 客户端使用

复制代码
public class Client {
    public static void main(String[] args) {
        Order order = new Order(1000);
        
        // 默认无促销
        System.out.println("原价: " + order.calculateFinalPrice());
        
        // 应用8折促销
        order.setPromotionStrategy(new DiscountPromotion(0.8));
        System.out.println("8折后: " + order.calculateFinalPrice());
        
        // 应用满1000减200
        order.setPromotionStrategy(new FullReductionPromotion(1000, 200));
        System.out.println("满减后: " + order.calculateFinalPrice());
    }
}

四、高级应用:策略工厂

1. 策略工厂类

复制代码
public class PromotionStrategyFactory {
    private static Map<String, PromotionStrategy> strategies = new HashMap<>();
    
    static {
        strategies.put("NO_PROMOTION", new NoPromotion());
        strategies.put("DISCOUNT_8", new DiscountPromotion(0.8));
        strategies.put("FULL_1000_REDUCE_200", new FullReductionPromotion(1000, 200));
    }
    
    public static PromotionStrategy getStrategy(String strategyKey) {
        PromotionStrategy strategy = strategies.get(strategyKey);
        if(strategy == null) {
            throw new IllegalArgumentException("无效的策略类型");
        }
        return strategy;
    }
}

2. 改进的订单类

复制代码
public class ImprovedOrder {
    private double amount;
    private PromotionStrategy promotionStrategy;
    
    public ImprovedOrder(double amount, String strategyKey) {
        this.amount = amount;
        this.promotionStrategy = PromotionStrategyFactory.getStrategy(strategyKey);
    }
    
    public double calculateFinalPrice() {
        return promotionStrategy.applyPromotion(amount);
    }
}

五、模式优势

  1. 符合开闭原则:新增策略无需修改现有代码
  2. 避免多重条件判断语句
  3. 提高算法的复用性和灵活性
  4. 算法可以自由切换

六、适用场景

  1. 系统需要在多种算法间动态切换
  2. 存在多个条件分支的复杂条件语句
  3. 需要隔离算法实现细节
  4. 算法需要自由组合的场景

七、注意事项

  1. 客户端必须了解所有策略的区别
  2. 会增加策略类的数量
  3. 策略对象会增大系统开销
  4. 适合算法经常变化的场景

八、与其他模式的关系

  • 与状态模式:策略模式改变对象行为,状态模式改变对象状态
  • 与工厂模式:常组合使用,策略工厂管理策略实例
  • 与模板方法模式:都是封装算法,策略用组合,模板用继承

九、最佳实践

  1. 将策略定义为轻量级的无状态对象
  2. 使用枚举或工厂管理策略实例
  3. 考虑使用Lambda表达式简化策略实现(Java8+)
  4. 为策略接口提供合理的默认实现
  5. 保持策略接口的简洁性

十、完整示例代码结构

java 复制代码
src/
├── main/
│ ├── java/
│ │ ├── strategy/
│ │ │ ├── PromotionStrategy.java
│ │ │ ├── NoPromotion.java
│ │ │ ├── DiscountPromotion.java
│ │ │ ├── FullReductionPromotion.java
│ │ │ ├── PromotionStrategyFactory.java
│ │ │ ├── Order.java
│ │ │ └── Client.java
相关推荐
文丑颜不良啊1 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang2 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪3 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息3 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼3 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff4 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff5 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
SL_staff6 小时前
JVS数字底座实践:构建企业级统一内容管理平台的技术路径
java·产品
nice_lcj5206 小时前
【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端
java·后端·spring·spring ai·ai应用开发
桦说编程7 小时前
TransmittableThreadLocal 解读:从 CRR 机制到上下文所有权
java·后端·源码