本文介绍如何使用策略模式统一事件处理流程,并结合访问者模式或错误类型多态分发,彻底消除 instanceof 判断导致的硬编码错误分支,提升面向对象设计的可扩展性与可维护性。
本文介绍如何使用策略模式统一事件处理流程,并结合访问者模式或错误类型多态分发,彻底消除 `instanceof` 判断导致的硬编码错误分支,提升面向对象设计的可扩展性与可维护性。
在原始代码中,EventProcessor 类通过大量 if (result instanceof XxxError) 分支对不同错误类型执行差异化状态设置(如 RETRYABLE、REJECTED、FAILED),不仅违反开闭原则,还导致 onEvent1 和 onEvent2 方法高度重复,难以新增事件类型或错误响应逻辑。
✅ 推荐方案:策略模式 + 错误行为多态化
与其让调用方(如 onEvent1)感知具体错误子类,不如将“错误发生后应执行的动作”封装为可插拔的行为。核心改造思路如下:
-
定义统一错误接口,支持行为委托
将 Error 抽象为具备“自我处理能力”的接口,各子类负责定义自身对应的业务动作:
public interface Error {
void handle(Event event); // 由错误自己决定如何影响事件状态
}
public class NoProcessorFoundError implements Error {
@Override
public void handle(Event event) {
if (event instanceof Event1) {
((Event1) event).setStatus(RETRYABLE);
} else if (event instanceof Event2) {
((Event2) event).setStatus(REJECTED);
}
// 其他通用日志/告警等
}
}
public class UnknownError implements Error {
@Override
public void handle(Event event) {
event.setStatus(FAILED); // 假设所有事件共用 FAILED 状态
}
}? 注意:此处 Event 应为 Event1 与 Event2 的公共父接口或抽象基类,确保类型安全。若二者无继承关系,可引入标记接口 Event 或使用泛型约束。
-
统一处理器:基于策略抽象事件处理流程
提取 EventProcessor 中重复逻辑,构建泛型策略处理器:
public interface EventProcessorStrategy<T extends Event> {
Error process(T event);
}
// 实现类解耦具体逻辑
public class Event1Processor implements EventProcessorStrategy<Event1> {
@Override
public Error process(Event1 event) {
try {
Event1Processors.process(event);
return null; // 表示成功,无错误
} catch (NoProcessorFoundException e) {
return new NoProcessorFoundError();
} catch (Exception e) {
return new UnknownError();
}
}
}
public class Event2Processor implements EventProcessorStrategy<Event2> {
@Override
public Error process(Event2 event) {
try {
Event2Processors.process(event);
return null;
} catch (NoProcessorFoundException e) {
return new NoProcessorFoundError();
} catch (Exception e) {
return new UnknownError();
}
}
}-
重构主处理器:消除分支,依赖多态分发
EventProcessor 不再关心错误类型,仅协调流程:
public class EventProcessor {
private final Map<Class<?>, EventProcessorStrategy<?>> strategies = new HashMap<>();
public EventProcessor() {
strategies.put(Event1.class, new Event1Processor());
strategies.put(Event2.class, new Event2Processor());
}
public <T extends Event> void onEvent(T event) {
@SuppressWarnings("unchecked")
EventProcessorStrategy<T> strategy = (EventProcessorStrategy<T>) strategies.get(event.getClass());
if (strategy == null) {
throw new UnsupportedOperationException("No processor registered for " + event.getClass().getSimpleName());
}
Error error = strategy.process(event);
if (error != null) {
error.handle(event); // 多态调用,零 if-else!
}
}
}⚠️ 关键注意事项
- 避免强制类型转换风险:NoProcessorFoundError.handle() 中的 instanceof 仅用于差异化状态设置,属合理边界逻辑;若未来状态规则进一步复杂(如按事件元数据动态决策),建议升级为 Visitor 模式 或策略映射表。
- 错误构造应轻量:Error 实例不应携带重资源(如数据库连接),推荐使用不可变对象 + 工厂方法。
- 扩展性保障:新增事件类型时,只需实现 EventProcessorStrategy 并注册到 strategies 映射表,无需修改任何已有 if-else 或 switch。
- 异常 vs 返回值权衡:当前采用返回 Error 对象方式,适合控制流清晰的场景;若错误极少见,亦可改用受检异常(throws NoProcessorFoundException),由调用方 try-catch 处理,同样可规避 instanceof。
✅ 总结
通过将“错误如何响应”下沉至错误类型自身(多态 handle()),并用策略模式隔离不同事件的处理逻辑,我们一举解决了两大痛点:
? 消除了重复的 if-else instanceof 分支;
? 将变化点(事件类型、错误响应规则)分别封装进独立类,符合单一职责与开闭原则。
该设计既保持代码简洁性,又为未来支持 Event3、TimeoutError 等扩展预留了干净的架构入口。

















