一、传统策略模式的痛点与突破
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;
}
}
}
六、最佳实践总结
合理定义策略边界:每个策略应聚焦单一职责
统一异常处理:定义策略执行异常体系
版本控制策略:支持多版本策略共存
动态配置支持:结合配置中心实现热更新
性能优化:缓存高频使用策略