如何实现Java策略模式?Spring中无if语句的多态事件处理器匹配方法
在Spring中实现无if分支的策略模式(基于Event匹配处理器)
核心思路
通过Spring的依赖注入能力,将Event类型与对应处理器自动绑定,利用注解标记处理器负责的事件类型,最终通过调度器实现事件到处理器的自动匹配,完全避免if/else判断。
1. 定义核心组件
1.1 Event接口与具体事件类
先定义通用的Event接口,再实现对应业务场景的具体事件:
public interface Event { String getEventId(); // 通用事件方法,可根据业务扩展 } // 订单创建事件 public class OrderCreatedEvent implements Event { private String eventId; private String orderId; public OrderCreatedEvent(String eventId, String orderId) { this.eventId = eventId; this.orderId = orderId; } @Override public String getEventId() { return eventId; } public String getOrderId() { return orderId; } } // 支付失败事件 public class PaymentFailedEvent implements Event { private String eventId; private String paymentId; private String errorMsg; public PaymentFailedEvent(String eventId, String paymentId, String errorMsg) { this.eventId = eventId; this.paymentId = paymentId; this.errorMsg = errorMsg; } @Override public String getEventId() { return eventId; } public String getPaymentId() { return paymentId; } public String getErrorMsg() { return errorMsg; } }
1.2 处理器接口与绑定注解
定义处理器接口,并通过自定义注解标记该处理器对应的事件类型:
// 自定义注解:标记处理器负责的Event类型 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface HandlesEvent { Class<? extends Event> value(); } // 通用处理器接口 public interface EventProcessor<T extends Event> { void process(T event); }
2. 实现具体事件处理器
每个处理器实现EventProcessor,并通过@Component和@HandlesEvent注册到Spring容器:
@Component @HandlesEvent(OrderCreatedEvent.class) public class OrderCreatedProcessor implements EventProcessor<OrderCreatedEvent> { @Override public void process(OrderCreatedEvent event) { System.out.println("处理订单创建事件:订单ID=" + event.getOrderId()); // 实际业务逻辑:生成发货单、发送用户通知等 } } @Component @HandlesEvent(PaymentFailedEvent.class) public class PaymentFailedProcessor implements EventProcessor<PaymentFailedEvent> { @Override public void process(PaymentFailedEvent event) { System.out.println("处理支付失败事件:支付ID=" + event.getPaymentId() + ",错误信息=" + event.getErrorMsg()); // 实际业务逻辑:触发退款、发送告警通知等 } }
3. 实现事件调度器(核心匹配逻辑)
通过Spring注入所有处理器,初始化Event类型-处理器的映射关系,提供统一的事件分发方法:
@Component public class EventProcessorDispatcher { private final Map<Class<? extends Event>, EventProcessor<? extends Event>> processorMap; // 构造注入所有处理器,自动建立映射 public EventProcessorDispatcher(List<EventProcessor<? extends Event>> processors) { this.processorMap = processors.stream() .collect(Collectors.toMap( processor -> { HandlesEvent annotation = processor.getClass().getAnnotation(HandlesEvent.class); if (annotation == null) { throw new IllegalArgumentException("处理器" + processor.getClass().getName() + "未标注@HandlesEvent注解"); } return annotation.value(); }, processor -> processor )); } @SuppressWarnings("unchecked") public void dispatch(Event event) { EventProcessor<Event> processor = (EventProcessor<Event>) processorMap.get(event.getClass()); if (processor == null) { throw new UnsupportedOperationException("未找到事件[" + event.getClass().getName() + "]对应的处理器"); } processor.process(event); } }
4. 使用示例
在业务服务中调用调度器,传入解析后的Event实例即可自动匹配处理器:
@Service public class EventService { private final EventProcessorDispatcher dispatcher; public EventService(EventProcessorDispatcher dispatcher) { this.dispatcher = dispatcher; } public void handleEventString(String eventStr) { // 模拟从字符串解析Event实例(实际场景可使用JSON工具如Jackson解析) Event event = parseEventFromString(eventStr); dispatcher.dispatch(event); } // 模拟解析逻辑 private Event parseEventFromString(String eventStr) { if (eventStr.contains("orderCreated")) { return new OrderCreatedEvent("event_001", "order_123"); } else if (eventStr.contains("paymentFailed")) { return new PaymentFailedEvent("event_002", "pay_456", "账户余额不足"); } throw new IllegalArgumentException("无法解析的事件字符串"); } }
优势说明
- 完全消除if/else分支,通过多态和Spring自动映射实现事件匹配
- 新增事件与处理器时,只需实现对应接口并添加注解,无需修改调度器代码,符合开闭原则
- 泛型约束保证类型安全,避免强制转换风险
内容的提问来源于stack exchange,提问作者salvatore
相关产品推荐
相关产品推荐

