java中可通过泛型抽象类封装观察者模式,统一管理观察者列表与通知逻辑,强制子类实现事件触发点,支持并发安全、多种事件类型及常见陷阱规避。

在 Java 中,可以通过抽象类封装观察者模式的核心逻辑,让子类只需关注具体事件类型和业务处理,无需重复实现注册、通知等通用机制。
定义泛型抽象基类
用泛型约束事件类型,避免运行时类型转换问题。抽象类持有观察者列表,并提供注册、移除、通知的统一方法:
- 声明 protected List
> observers = new ArrayList(); - 提供 addObserver(Consumer
observer) 和 removeObserver(Consumerobserver) 方法 - 定义 protected void notifyObservers(T event),遍历调用每个观察者
- 可选:加同步块或使用 CopyOnWriteArrayList 支持并发安全
强制子类明确事件触发点
抽象类不决定“何时发事件”,而是把触发时机留给子类。通过 protected abstract void fireEvent(T event) 或更语义化的方法(如 onDataUpdated())要求子类实现具体通知逻辑:
- 子类在状态变更后调用该方法,传入对应事件对象(如 new DataChangedEvent(data))
- 避免在抽象类中硬编码事件条件,保持解耦
- 可配合模板方法,在 fireEvent 前后留钩子(如 beforeNotify() / afterNotify())
支持多种事件类型与组合
一个抽象基类可适配不同事件场景,关键在于泛型与职责分离:
- 定义多个具体事件类(UserLoginEvent、ConfigReloadEvent),各自继承或实现标记接口
- 子类按需指定泛型参数:extends EventNotifier
- 若需监听多种事件,可让子类维护多个观察者列表,或用事件总线+过滤器替代(此时抽象基类退化为单事件载体)
避免常见陷阱
实际使用中要注意几个易错点:
- 观察者引用未及时清理会导致内存泄漏,建议配合 WeakReference
> 或提供显式注销机制 - 通知过程发生异常会中断后续观察者执行,可在 notifyObservers 中 try-catch 单个观察者调用
- 不要在观察者回调里修改被观察对象状态,否则可能引发递归通知或状态不一致
- 抽象类本身不 new 观察者,也不持有具体业务逻辑,只做调度中枢
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











