Java行为型模式---策略模式

策略模式基础概念

策略模式(Strategy Pattern)是一种行为型设计模式,其核心思想是定义一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,符合开闭原则(对扩展开放,对修改关闭)。

策略模式的核心组件

  1. 策略接口(Strategy) - 定义所有支持的算法的公共接口
  2. 具体策略(ConcreteStrategy) - 实现策略接口的具体算法
  3. 上下文(Context) - 持有一个策略接口的引用,负责根据需要选择和使用具体策略
  4. 客户端(Client) - 创建并配置上下文对象,选择合适的策略

策略模式的实现

下面通过一个电商系统的折扣计算示例展示策略模式的实现:

复制代码
// 策略接口 - 折扣计算
interface DiscountStrategy {
    double applyDiscount(double originalPrice);
}

// 具体策略 - 无折扣
class NoDiscount implements DiscountStrategy {
    @Override
    public double applyDiscount(double originalPrice) {
        return originalPrice;
    }
}

// 具体策略 - 固定金额折扣
class FixedAmountDiscount implements DiscountStrategy {
    private double discountAmount;
    
    public FixedAmountDiscount(double discountAmount) {
        this.discountAmount = discountAmount;
    }
    
    @Override
    public double applyDiscount(double originalPrice) {
        return Math.max(0, originalPrice - discountAmount);
    }
}

// 具体策略 - 百分比折扣
class PercentageDiscount implements DiscountStrategy {
    private double discountPercentage;
    
    public PercentageDiscount(double discountPercentage) {
        this.discountPercentage = discountPercentage;
    }
    
    @Override
    public double applyDiscount(double originalPrice) {
        return originalPrice * (1 - discountPercentage / 100);
    }
}

// 上下文 - 购物车
class ShoppingCart {
    private DiscountStrategy discountStrategy;
    
    public ShoppingCart() {
        // 默认无折扣
        this.discountStrategy = new NoDiscount();
    }
    
    // 设置折扣策略
    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
    
    // 计算折扣后的价格
    public double calculateTotal(double originalPrice) {
        return discountStrategy.applyDiscount(originalPrice);
    }
}

// 客户端代码
public class StrategyPatternClient {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        double originalPrice = 1000.0;
        
        // 使用无折扣策略
        cart.setDiscountStrategy(new NoDiscount());
        System.out.println("原价: " + originalPrice);
        System.out.println("无折扣价格: " + cart.calculateTotal(originalPrice));
        
        // 使用固定金额折扣策略(减200元)
        cart.setDiscountStrategy(new FixedAmountDiscount(200.0));
        System.out.println("固定金额折扣价格: " + cart.calculateTotal(originalPrice));
        
        // 使用百分比折扣策略(打8折)
        cart.setDiscountStrategy(new PercentageDiscount(20.0));
        System.out.println("百分比折扣价格: " + cart.calculateTotal(originalPrice));
    }
}

策略模式的应用场景

  1. 算法选择 - 当系统需要在多个算法中动态选择一个时
  2. 避免条件语句 - 用策略模式替代复杂的 if-else 或 switch 语句
  3. 行为扩展 - 当需要在运行时动态更改对象的行为时
  4. 多种实现方式 - 当一个问题有多种解决方式,且需要在运行时切换时
  5. 权限控制 - 根据不同用户角色应用不同的访问策略

策略模式与状态模式的对比

特性 策略模式 状态模式
核心目的 算法的替换和选择 对象状态的管理和转换
客户端控制 客户端主动选择策略 状态转换由上下文或状态自身控制
状态数量 策略之间无关联,数量固定 状态之间有关联,数量可能动态变化
结构复杂度 简单,策略之间相互独立 复杂,状态之间有转换逻辑
典型应用 支付方式、排序算法、折扣计算 工作流状态、游戏角色状态

策略模式的优缺点

优点

  • 符合开闭原则 - 可以在不修改原有代码的情况下新增策略
  • 消除条件语句 - 避免使用大量的 if-else 或 switch 语句
  • 提高代码复用性 - 策略可以被多个上下文复用
  • 简化单元测试 - 每个策略可以独立测试
  • 解耦算法与客户端 - 客户端不需要了解算法的具体实现

缺点

  • 类数量增加 - 每个策略都需要一个独立的类,可能导致类爆炸
  • 客户端必须了解策略差异 - 客户端需要知道不同策略的区别才能选择
  • 策略与上下文耦合 - 上下文需要理解策略接口,可能存在一定耦合
  • 不适合简单场景 - 对于简单的算法选择,使用策略模式可能过于复杂

使用策略模式的注意事项

  1. 合理设计策略接口 - 确保策略接口简洁且满足需求
  2. 策略的创建与管理 - 可以使用工厂模式或配置文件来管理策略的创建
  3. 避免过度使用 - 仅在确实需要动态切换算法时使用
  4. 考虑策略组合 - 可以通过组合多个策略实现更复杂的行为
  5. 使用枚举策略 - 对于固定且简单的策略,可以考虑使用枚举实现

策略模式是一种非常实用的设计模式,它通过将算法封装并使其可互换,提高了代码的灵活性和可维护性。在实际开发中,策略模式常用于电商折扣系统、支付方式选择、游戏 AI 等需要动态选择算法的场景。

相关推荐
AI必将改变世界4 分钟前
【软考系统架构设计师备考笔记5】 - 专业英语
java·开发语言·人工智能·笔记·系统架构·英语
_祝你今天愉快7 分钟前
Java Lock
android·java·后端
listhi5208 分钟前
Python实现信号小波分解与重构
开发语言·python·重构
熊猫片沃子39 分钟前
mybatis 与mybatisplus 比较总结
java·后端·mybatis
骑驴看星星a42 分钟前
层次分析法代码笔记
开发语言·笔记·python·numpy
Elastic 中国社区官方博客1 小时前
升级 Elasticsearch 到新的 AWS Java SDK
java·大数据·elasticsearch·搜索引擎·云计算·全文检索·aws
枣伊吕波1 小时前
十一、请求响应-请求:简单参数和实体参数(简单实体参数与复杂实体参数)
java·spring boot·后端
苇柠2 小时前
SpringMVC基础
java·后端·spring
xingzizhanlan2 小时前
apache-tomcat-11.0.9安装及环境变量配置
java·tomcat·apache
Sunlightʊə2 小时前
05.LinkedList与链表
java·数据结构·算法·链表