泛型加持的策略模式:打造高扩展的通用策略工具类

发布于:2025-05-11 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、传统策略模式的痛点与突破

1.1 传统策略实现回顾

// 传统支付策略接口
public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

// 具体策略实现
public class AlipayStrategy implements PaymentStrategy {
    public void pay(BigDecimal amount) { /* 支付宝支付逻辑 */ }
}

// 策略上下文
public class PaymentContext {
    private PaymentStrategy strategy;
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void executePayment(BigDecimal amount) {
        strategy.pay(amount);
    }
}

存在问题
❌ 策略类型固定,无法通用化
❌ 新增策略需修改上下文类
❌ 无法动态管理策略集合


二、泛型化策略工具类设计

2.1 核心接口定义

/**
 * 通用策略接口
 * @param <T> 策略参数类型
 * @param <R> 返回结果类型
 */
public interface GenericStrategy<T, R> {
    /**
     * 是否支持当前策略类型
     */
    boolean support(String strategyType);
    
    /**
     * 执行策略
     */
    R apply(T param);
}

2.2 策略上下文工具类

public class StrategyContext<T, R> {
    private final Map<String, GenericStrategy<T, R>> strategyMap = new ConcurrentHashMap<>();
    
    /**
     * 注册策略
     */
    public void registerStrategy(String strategyType, GenericStrategy<T, R> strategy) {
        strategyMap.put(strategyType, strategy);
    }
    
    /**
     * 执行策略
     */
    public R execute(String strategyType, T param) {
        GenericStrategy<T, R> strategy = Optional.ofNullable(strategyMap.get(strategyType))
            .orElseThrow(() -> new IllegalArgumentException("未找到策略: " + strategyType));
        return strategy.apply(param);
    }
    
    /**
     * 批量执行策略
     */
    public List<R> executeAll(T param) {
        return strategyMap.values().stream()
            .map(s -> s.apply(param))
            .collect(Collectors.toList());
    }
}

三、Spring集成与自动装配

3.1 自动注册策略实现

@Configuration
public class StrategyAutoConfiguration {
    
    /**
     * 自动发现所有策略Bean并注册
     */
    @Bean
    public <T, R> StrategyContext<T, R> strategyContext(
        List<GenericStrategy<T, R>> strategies) {
        StrategyContext<T, R> context = new StrategyContext<>();
        strategies.forEach(strategy -> 
            context.registerStrategy(
                strategy.getClass().getAnnotation(StrategyType.class).value(),
                strategy
            )
        );
        return context;
    }
}

/**
 * 策略类型注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface StrategyType {
    String value();
}

3.2 策略实现示例

@StrategyType("alipay")
@Component
public class AlipayStrategy implements GenericStrategy<PaymentRequest, PaymentResult> {
    @Override
    public boolean support(String strategyType) {
        return "alipay".equals(strategyType);
    }
    
    @Override
    public PaymentResult apply(PaymentRequest request) {
        // 支付宝支付具体实现
    }
}

四、企业级应用案例

4.1 支付策略路由

@RestController
@RequestMapping("/payment")
public class PaymentController {
    @Autowired
    private StrategyContext<PaymentRequest, PaymentResult> paymentContext;
    
    @PostMapping("/{type}")
    public PaymentResult pay(@PathVariable String type, @RequestBody PaymentRequest request) {
        return paymentContext.execute(type, request);
    }
}

4.2 动态折扣计算

public enum DiscountType {
    NEW_USER, 
    FESTIVAL, 
    VIP_LEVEL
}

public class DiscountStrategy implements GenericStrategy<DiscountType, BigDecimal> {
    private static final Map<DiscountType, BigDecimal> DISCOUNT_MAP = Map.of(
        DiscountType.NEW_USER, new BigDecimal("0.9"),
        DiscountType.FESTIVAL, new BigDecimal("0.8"),
        DiscountType.VIP_LEVEL, new BigDecimal("0.7")
    );
    
    @Override
    public boolean support(String strategyType) {
        return Arrays.stream(DiscountType.values())
            .anyMatch(e -> e.name().equals(strategyType));
    }
    
    @Override
    public BigDecimal apply(DiscountType type) {
        return DISCOUNT_MAP.get(type);
    }
}

五、高级功能扩展

5.1 策略优先级控制

public class PriorityStrategyContext<T, R> extends StrategyContext<T, R> {
    private final PriorityQueue<GenericStrategy<T, R>> priorityQueue = 
        new PriorityQueue<>(Comparator.comparingInt(this::getPriority));
    
    private int getPriority(GenericStrategy<T, R> strategy) {
        return strategy.getClass().isAnnotationPresent(StrategyPriority.class) ?
            strategy.getClass().getAnnotation(StrategyPriority.class).value() : 0;
    }
    
    @Override
    public void registerStrategy(String type, GenericStrategy<T, R> strategy) {
        super.registerStrategy(type, strategy);
        priorityQueue.offer(strategy);
    }
    
    public R executeFirst(T param) {
        return priorityQueue.peek().apply(param);
    }
}

5.2 策略执行监控

public class MonitoredStrategyContext<T, R> extends StrategyContext<T, R> {
    private final MeterRegistry meterRegistry;
    
    @Override
    public R execute(String strategyType, T param) {
        Timer.Sample sample = Timer.start(meterRegistry);
        try {
            R result = super.execute(strategyType, param);
            sample.stop(meterRegistry.timer("strategy.execute.time", "type", strategyType));
            return result;
        } catch (Exception e) {
            meterRegistry.counter("strategy.error", "type", strategyType).increment();
            throw e;
        }
    }
}

六、最佳实践总结

  1. 合理定义策略边界:每个策略应聚焦单一职责

  2. 统一异常处理:定义策略执行异常体系

  3. 版本控制策略:支持多版本策略共存

  4. 动态配置支持:结合配置中心实现热更新

  5. 性能优化:缓存高频使用策略