深度解析策略模式:从理论到企业级实战应用

发布于:2025-02-11 ⋅ 阅读:(14) ⋅ 点赞:(0)

一、策略模式的本质:面向接口的算法工厂

策略模式(Strategy Pattern)是行为型设计模式的典型代表,其核心思想是将算法族抽象为独立对象,使其能够相互替换。这种模式完美体现了以下面向对象设计原则:

  1. 开闭原则(OCP):新增策略无需修改已有代码

  2. 单一职责原则(SRP):每个策略只负责特定算法

  3. 依赖倒置原则(DIP):高层模块依赖抽象而非具体实现

UML类图


二、策略模式的三种典型实现方式

1. 基础版实现(传统方式)

// 策略接口
public interface DiscountStrategy {
    BigDecimal calculateDiscount(BigDecimal amount);
}

// 具体策略
public class VipDiscount implements DiscountStrategy {
    @Override
    public BigDecimal calculateDiscount(BigDecimal amount) {
        return amount.multiply(new BigDecimal("0.8"));
    }
}

public class FestivalDiscount implements DiscountStrategy {
    @Override
    public BigDecimal calculateDiscount(BigDecimal amount) {
        return amount.subtract(new BigDecimal("50"));
    }
}

// 上下文环境
public class OrderContext {
    private DiscountStrategy strategy;

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

    public BigDecimal executeDiscount(BigDecimal amount) {
        return strategy.calculateDiscount(amount);
    }
}

2. 枚举策略(简化分支判断)

public enum CalculatorStrategy {
    ADD {
        @Override
        public int execute(int a, int b) { return a + b; }
    },
    SUBTRACT {
        @Override
        public int execute(int a, int b) { return a - b; }
    };

    public abstract int execute(int a, int b);
}

3. Spring集成版(企业级实践)

// 定义策略接口
public interface PaymentStrategy {
    void processPayment(BigDecimal amount);
}

// 实现策略(带Spring注解)
@Component("alipayStrategy")
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public void processPayment(BigDecimal amount) {
        // 支付宝支付逻辑
    }
}

@Component("wechatPayStrategy")
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public void processPayment(BigDecimal amount) {
        // 微信支付逻辑
    }
}

// 策略上下文(自动注入策略集合)
@Service
public class PaymentContext {
    @Autowired
    private Map<String, PaymentStrategy> strategyMap;

    public void executePayment(String paymentType, BigDecimal amount) {
        PaymentStrategy strategy = strategyMap.get(paymentType + "Strategy");
        if (strategy != null) {
            strategy.processPayment(amount);
        } else {
            throw new IllegalArgumentException("Unsupported payment type");
        }
    }
}

三、策略模式的六大应用场景

场景1:电商促销系统

  • 满减策略

  • 折扣策略

  • 赠品策略

  • 积分抵现策略

场景2:支付网关路由

  • 支付宝支付

  • 微信支付

  • 银联支付

  • 数字货币支付

场景3:日志处理系统

  • 本地文件存储

  • 云存储(OSS/S3)

  • 消息队列转发

  • 数据库存储

场景4:数据校验引擎

  • 手机号校验

  • 身份证校验

  • 邮箱校验

  • 地址校验

场景5:游戏AI系统

  • 攻击策略

  • 防御策略

  • 逃跑策略

  • 补给策略

场景6:报表生成系统

  • PDF生成

  • Excel生成

  • HTML生成

  • CSV生成


四、策略模式与相关模式的深度对比

模式 关注点 与策略模式的关系
工厂模式 对象创建 策略模式常配合工厂创建具体策略
状态模式 状态转换 状态改变行为,策略改变算法
模板方法模式 算法步骤 策略替换整个算法,模板方法替换步骤
命令模式 请求封装 策略是主动选择,命令是被动触发

五、企业级实战:支付系统策略架构设计

架构图

复制

[支付请求] --> [支付网关]
                   ↓
           [策略路由中心]
                   ↓
+----------------+----------------+
| 支付宝策略     | 微信支付策略    | 银联策略
+----------------+----------------+
                   ↓
           [渠道适配层]
                   ↓
          [第三方支付平台]

代码实现(Spring Boot +策略模式)

java

复制

// 支付策略接口
public interface PaymentStrategy {
    PaymentResult pay(PaymentRequest request);
}

// 支付宝策略实现
@Component
public class AlipayStrategy implements PaymentStrategy {
    @Override
    @PaymentType(PayChannel.ALIPAY)
    public PaymentResult pay(PaymentRequest request) {
        // 调用支付宝SDK
        return new PaymentResult(true, "ALIPAY-123456");
    }
}

// 策略工厂(自动发现策略)
@Component
public class PaymentStrategyFactory {
    @Autowired
    private Map<String, PaymentStrategy> strategyMap;

    public PaymentStrategy getStrategy(PayChannel channel) {
        return strategyMap.values().stream()
                .filter(s -> s.getClass().isAnnotationPresent(PaymentType.class))
                .filter(s -> s.getClass().getAnnotation(PaymentType.class).value() == channel)
                .findFirst()
                .orElseThrow(() -> new RuntimeException("未找到支付策略"));
    }
}

// 支付服务
@Service
@RequiredArgsConstructor
public class PaymentService {
    private final PaymentStrategyFactory strategyFactory;

    public PaymentResult processPayment(PaymentRequest request) {
        PaymentStrategy strategy = strategyFactory.getStrategy(request.getChannel());
        return strategy.pay(request);
    }
}

六、策略模式的五个优化技巧

1. 策略预热缓存

public class StrategyCache {
    private static final Map<String, Strategy> cache = new ConcurrentHashMap<>();

    public static Strategy getStrategy(String type) {
        return cache.computeIfAbsent(type, t -> {
            // 动态加载策略类
            try {
                return (Strategy) Class.forName(t).newInstance();
            } catch (Exception e) {
                throw new RuntimeException("策略加载失败");
            }
        });
    }
}

2. 策略权重配置

# application.yml
payment:
  strategies:
    alipay: 
      weight: 60
      enable: true
    wechat: 
      weight: 30  
      enable: true
    unionpay: 
      weight: 10
      enable: false

3. 策略性能监控

public class MonitoredStrategy implements Strategy {
    private final Strategy delegate;
    private final MeterRegistry registry;

    public MonitoredStrategy(Strategy delegate, MeterRegistry registry) {
        this.delegate = delegate;
        this.registry = registry;
    }

    @Override
    public void execute() {
        Timer.Sample sample = Timer.start(registry);
        try {
            delegate.execute();
        } finally {
            sample.stop(registry.timer("strategy.execution.time", "type", delegate.getClass().getSimpleName()));
        }
    }
}

七、常见陷阱与解决方案

陷阱 现象 解决方案
策略状态共享 线程安全问题 使用ThreadLocal或每次新建策略实例
策略膨胀失控 类数量爆炸 使用DSL动态生成策略类
策略切换开销大 频繁切换影响性能 引入策略缓存池
策略配置错误 运行时找不到策略 增加策略fallback机制
策略执行顺序依赖 策略之间存在依赖关系 引入策略责任链模式

网站公告

今日签到

点亮在社区的每一天
去签到