
本文介绍如何利用策略模式统一事件处理流程,并结合访问者模式(或更轻量的错误处理器注册机制)彻底消除 instanceof 判断错误类型的 if-else 分支,提升面向对象设计的可扩展性与可维护性。
本文介绍如何利用策略模式统一事件处理流程,并结合访问者模式(或更轻量的错误处理器注册机制)彻底消除 `instanceof` 判断错误类型的 if-else 分支,提升面向对象设计的可扩展性与可维护性。
在原始代码中,EventProcessor 类通过硬编码的 if (result instanceof XxxError) 对不同错误子类做差异化状态设置(如 RETRYABLE、REJECTED、FAILED),不仅违反开闭原则——新增错误类型需修改所有 onEventX 方法,还导致业务逻辑(状态变更、日志、重试策略等)与错误判定严重耦合。
✅ 推荐方案:策略模式 + 错误处理器注册表(优于命令模式)
虽然答案提到了命令模式,但其示例中仍将错误处理逻辑重复写入每个 ProcessX.execute(),未真正解耦错误响应行为。更优解是分离“错误产生”与“错误响应”:
-
定义统一错误接口与具体实现(保持原有继承结构):
abstract class ProcessingError extends RuntimeException { abstract void handle(Event event); // 模板方法:由子类决定如何响应 }
class NoProcessorFoundError extends ProcessingError { @Override void handle(Event event) { if (event instanceof Event1) ((Event1) event).setStatus(RETRYABLE); else if (event instanceof Event2) ((Event2) event).setStatus(REJECTED); // 可扩展:记录指标、触发告警等 } }
class UnknownError extends ProcessingError { @Override void handle(Event event) { event.setStatus(FAILED); // 公共逻辑可在此统一 // 例如:发送监控埋点 } }
2. **抽象事件基类,支持多态处理**:
```java
interface Event {
void setStatus(Status status);
}
class Event1 implements Event { /* ... */ }
class Event2 implements Event { /* ... */ }-
重构处理器:统一调度,委托错误处理:
public class EventProcessor { // 策略模式:将 processX 合并为泛型方法 public <T extends Event> void onEvent(T event, EventProcessorStrategy<T> strategy) { try { ProcessingError error = strategy.process(event); if (error != null) { error.handle(event); // 多态分发,零 if-else! } } catch (Exception e) { new UnknownError().handle(event); // 统一兜底 } } // 使用示例 public void onEvent1(Event1 event1) { onEvent(event1, Event1ProcessorStrategy.INSTANCE); } public void onEvent2(Event2 event2) { onEvent(event2, Event2ProcessorStrategy.INSTANCE); } }
// 策略接口 & 实现(职责单一,易测试)
interface EventProcessorStrategy
class Event1ProcessorStrategy implements EventProcessorStrategy
### ⚠️ 注意事项与进阶建议 - **避免 Visitor 的过度设计**:Visitor 模式虽能彻底消除 `instanceof`,但需双向修改(增加 `accept()` 方法 + 访问者类),对简单错误分类属于杀鸡用牛刀。推荐优先使用上述「错误自包含行为」方式。 - **错误处理器可插拔**:若状态设置规则需运行时配置(如不同租户策略不同),可将 `handle()` 抽象为 `ErrorHandler` 接口,并通过 Spring Bean 或 Map 注册: ```java Map<Class<? extends ProcessingError>, BiConsumer<ProcessingError, Event>> handlers = new HashMap<>(); handlers.put(NoProcessorFoundError.class, (e, ev) -> ev.setStatus(...));
- 返回值语义优化:process() 方法返回 Optional<ProcessingError> 比返回 null/Error 更符合函数式风格,且避免空指针风险。
✅ 总结
消除 instanceof if-else 的本质,是将条件分支转化为多态分发或策略查找。本文方案通过:
- ✅ 错误类自身封装处理逻辑(handle()),实现“数据与行为绑定”;
- ✅ 通用 onEvent() 方法统一入口,配合策略对象隔离事件特异性;
- ✅ 零反射、零枚举、零 Map 查找,兼顾性能与可读性。
后续新增错误类型(如 TimeoutError)仅需继承 ProcessingError 并实现 handle(),无需触碰任何现有处理器代码——这才是面向对象设计所追求的优雅与弹性。

















