24.设计模式-Strategy(策略)

一、模式定义与核心价值

策略模式是一种行为型设计模式,其核心目标是定义一系列算法族,并将每个算法封装为独立对象,使其可动态替换。该模式通过解耦算法定义与使用逻辑,实现以下核心价值:

  1. 消除条件分支:避免大量if-elseswitch-case硬编码,提升代码可维护性(如电商促销活动的多算法切换)
  2. 开放扩展性:新增算法无需修改现有代码,符合开闭原则(如导航系统中新增骑行路线策略)
  3. 运行时灵活性:客户端可动态选择算法(如投资系统中的价值投资、成长投资策略切换)

经典场景

  • 支付网关的多渠道计费规则(微信支付、支付宝的费率计算)
  • 游戏角色的技能释放策略(普攻、连招、必杀技)
  • 数据压缩格式选择(ZIP、RAR、7z算法的动态切换)

二、模式组成与UML类图

核心角色
  1. Strategy(策略接口)
    • 定义算法的公共接口(如calculate()
  1. ConcreteStrategy(具体策略)
    • 实现接口的具体算法(如满减策略、折扣策略)
  1. Context(上下文)
    • 持有策略引用,通过接口调用算法(如订单结算系统)
UML类图
classDiagram
    class Context {
        -strategy: Strategy
        +setStrategy(Strategy)
        +executeStrategy()
    }

    interface Strategy {
        <<interface>>
        +execute()
    }

    class ConcreteStrategyA {
        +execute()
    }

    class ConcreteStrategyB {
        +execute()
    }

    Context --> Strategy
    Strategy <|.. ConcreteStrategyA
    Strategy <|.. ConcreteStrategyB


三、代码实现示例

场景:电商促销系统实现动态折扣策略(满减、百分比折扣、会员专属折扣)

1. 策略接口与实现
// 抽象策略接口
interface DiscountStrategy {
    double calculateDiscount(double originalPrice);
}

// 具体策略:满减策略
class FullReductionStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price > 200 ? price - 50 : price; // 满200减50
    }
}

// 具体策略:八折策略 
class PercentageDiscountStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.8;
    }
}
2. 上下文类
class ShoppingCart {
    private DiscountStrategy strategy;

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

    public double checkout(double originalPrice) {
        if (strategy == null) throw new IllegalStateException("未选择折扣策略");
        return strategy.calculateDiscount(originalPrice);
    }
}
3. 客户端调用
public class Client {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        // 动态切换策略
        cart.setStrategy(new FullReductionStrategy());
        System.out.println("满减后价格:" + cart.checkout(250)); // 输出200.0

        cart.setStrategy(new PercentageDiscountStrategy());
        System.out.println("八折后价格:" + cart.checkout(250)); // 输出200.0
    }
}

四、工业级源码应用

  1. Java集合框架
    • Comparator接口是典型策略模式,通过实现compare()方法定义不同排序策略(如Collections.sort()的定制排序)
  1. Spring框架
    • 资源加载策略ResourceLoader使用Resource策略接口支持类路径、文件系统、URL等多种资源加载方式
    • 事务管理PlatformTransactionManager定义事务策略,DataSourceTransactionManagerJpaTransactionManager为具体实现
  1. 智能合约开发
    • DeFi协议中动态定价机制(如线性定价与二次曲线定价策略的动态切换)
interface IPricingStrategy {
  function calculatePrice(uint256 amount) external view returns (uint256);
}
contract TokenSale {
  IPricingStrategy public strategy;
  function setStrategy(address _strategy) external onlyOwner {
    strategy = IPricingStrategy(_strategy);
  }
}
  1. Android UI系统
    • 动画插值器(TimeInterpolator):LinearInterpolatorAccelerateDecelerateInterpolator等策略实现动画速率曲线
  1. 机器学习框架
    • Scikit-learn的模型评估模块:scoring参数接受不同评估策略(准确率、F1值、AUC等)

五、模式对比与选型建议

对比维度 策略模式 工厂模式
核心目标 算法行为的动态切换 对象创建的解耦
扩展方向 横向扩展算法族 纵向扩展产品族
典型应用 支付费率计算、路由规划 数据库连接池、日志器

最佳实践建议

  1. 识别变化点:将频繁变更的算法逻辑剥离为策略类(如网页3的导航路线规划场景)
  2. 策略轻量化:避免策略类携带过多状态,优先设计无状态策略对象
  3. 结合注解:Spring项目中可用@Qualifier注解动态注入策略实现

总结

策略模式通过算法封装动态委派的机制,在电商促销、金融交易、智能合约等场景展现了强大的灵活性。其与工厂模式、模板方法模式的组合使用(如网页9的C++交易系统案例),更能构建出高扩展性的系统架构。开发者应重点识别业务中的高频变更算法,通过策略模式实现业务规则执行逻辑的优雅解耦。

posted @ 2025-04-12 11:23  雾里看花的少年  阅读(42)  评论(0)    收藏  举报