观察者模式的核心是状态变更时自动通知所有观察者更新。被观察者需封装状态并在setter中调用notifyAllObservers();观察者实现update()接口自主响应;须注意注册/解绑成对、线程安全及通知顺序。

观察者模式的核心作用,就是让多个对象能自动响应某个对象的变量变化,无需手动轮询或硬编码调用。关键不在于“谁通知谁”,而在于“状态一变,所有关心它的对象立刻知道并同步更新”。
被观察者要管好自己的状态和通知逻辑
被观察者(也叫主题、Subject)必须封装状态字段,并在 setter 中触发通知。不能只改值,不发消息。比如一个玩家类 Player,state 字段每次被修改,都要主动调用 notifyAllObservers():
- 定义私有状态变量(如 private String state)
- 提供 public void setState(String s) 方法,在方法末尾调用通知逻辑
- 内部维护 List
观察者列表,支持 add/remove 操作 - notify 方法需遍历列表,逐个调用 observer.update(this)
观察者要明确自己该响应什么、怎么更新
每个观察者实现统一的 update(Subject s) 接口,但具体行为由自己决定。它可以通过强转或接口方法获取被观察者的最新状态,然后刷新自身数据或界面。例如 UIObserver 可能更新 TextView,LogObserver 只是打印日志:
- update 方法里不要做耗时操作,避免阻塞通知流程
- 若需访问被观察者状态,优先通过 getter(如 s.getState()),而非直接读字段
- 避免在 update 中再次修改被观察者状态,防止循环通知
注册与解绑必须成对出现
观察者不是“一加了之”。尤其在生命周期敏感的场景(如 Android Activity、Vue 组件、React useEffect),必须在销毁前 removeObserver。否则容易引发内存泄漏或空指针异常:
- Activity onCreate 中 register,onDestroy 中 remove
- 组件 mounted 时注册,unmounted 时解绑
- 临时监听可使用一次性观察者,通知后自动移除
注意线程安全和通知顺序
多线程环境下,观察者列表的增删和遍历必须同步。Java 可用 CopyOnWriteArrayList,Kotlin 可用线程安全集合或协程上下文约束;JS/TS 虽单线程,但在 Promise 或 setTimeout 中异步更新仍需注意时序:
- 避免在 notify 过程中修改观察者列表(如某个 observer 自己调用 remove)
- 如需保证执行顺序,可对观察者排序,或分组通知(如先 UI 后日志)
- 高频状态变更时,考虑节流(throttle)或合并通知(如只通知最终值)

















