首页/开发/代码质量与评审速查/观察者模式 Observer(行为型)
设计原则与模式62 条

观察者模式 Observer(行为型)

一对多依赖:主题状态变化时通知所有订阅者(推送或拉取);事件总线、监听器、响应式流都是它的形态;注意退订、异常隔离与通知顺序。

观察者模式是什么

观察者建立一对多依赖:主题状态变化时通知所有订阅者,通知可以带数据(推送)也可以只发信号(拉取)。事件总线、监听器、响应式流都是它的形态。工程上真正需要设计的是退订、异常隔离与通知顺序,而不是通知这个动作本身。

基本信息

意图状态变更触发广播通知
两种形态推送(携带数据)与拉取(通知后自取)
工程要点退订、异常隔离、通知顺序与幂等
典型实现监听器注册表、事件总线、消息订阅
相关取舍同进程内用观察者,跨服务用消息中间件

典型使用场景

  • 领域事件触发通知与审计记录
  • 配置变更后刷新缓存
  • 界面或接口层的状态订阅
  • 指标与日志的旁路采集
  • 插件与扩展点注册回调

Java 示例

Java 示例
interface Listener { void onEvent(Event e); }

class Topic {
    private final List<Listener> listeners = new CopyOnWriteArrayList<>();

    void subscribe(Listener l) { listeners.add(l); }

    void publish(Event e) {
        for (Listener l : listeners) l.onEvent(e);   // 通知顺序即注册顺序
    }
}

通知机制的选择

机制适用注意
直接方法调用同进程、订阅方很少编译期耦合,扩展要改代码
观察者与事件总线同进程、多个订阅方需处理退订与异常隔离
消息中间件跨服务、需要持久化引入投递语义与去重问题
订阅者要能优雅退出:退订接口、弱引用或按生命周期销毁都是常见做法;忘记释放的监听器会一直收到回调,也会拖住对象不被回收。

发布方要做的事

  • 逐个通知时隔离异常,单个订阅者失败不影响其他订阅者
  • 为同步回调设置超时,避免主流程被旁路逻辑拖住
  • 明确通知顺序与幂等要求,必要时携带事件编号
  • 提供退订入口,并在对象销毁时自动清理订阅
一个订阅者抛异常拖垮整条广播,是观察者最典型的线上问题:发布方要做异常隔离与超时保护,别让旁路逻辑拖住主流程。

易错点

  • 监听器忘记退订:内存泄漏与幽灵回调,问题在长时间运行后才显现
  • 通知链无异常隔离:一个订阅者抛错拖垮整条广播
  • 下游依赖通知顺序:顺序变化时出现偶发不一致
  • 用通知代替业务事务:状态变更与通知不同步,数据与消息不一致

数据来源与参考

  • 《设计模式》(GoF)· Observer
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌