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
相关推荐
艾迪的技术之路8 分钟前
redisson使用lock导致死锁问题
java·后端·面试
今天背单词了吗98026 分钟前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
天天摸鱼的java工程师28 分钟前
使用 Spring Boot 整合高德地图实现路线规划功能
java·后端
东阳马生架构44 分钟前
订单初版—2.生单链路中的技术问题说明文档
java
咖啡啡不加糖1 小时前
暴力破解漏洞与命令执行漏洞
java·后端·web安全
风象南1 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端
DKPT1 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
Percep_gan1 小时前
idea的使用小技巧,个人向
java·ide·intellij-idea
缘来是庄1 小时前
设计模式之迭代器模式
java·设计模式·迭代器模式