核心是状态变更主动广播:被观察者封装setter通知、观察者实现update响应,双方解耦;需线程安全存储、严格注册解绑、节流防高频、避免notify中修改列表。

核心是让状态变更“自己说话”——被观察者改值时主动广播,观察者收到就响应,全程不互相持有、不硬编码调用。
被观察者要管住状态和通知出口
它不是普通数据容器,而是状态中枢。关键动作必须封装在 setter 里:
- 状态字段设为 private,禁止外部直接赋值
- 提供 public void setState(X x) 方法,在赋值后立即调用 notifyAllObservers()
- 内部用线程安全集合(如 Java 的 CopyOnWriteArrayList、JS 的 Set)存 observer 列表
- notify 方法只做一件事:遍历列表,逐个调用 observer.update(this) 或 observer.update(data)
观察者只认接口,不认具体类
每个观察者只需实现统一 update 方法,行为完全自主:
- UI 观察者可刷新 DOM 或组件状态
- 日志观察者只 console.log 或写入文件
- 校验观察者可触发合法性检查,但不要反向修改被观察者状态(防循环)
- update 中避免耗时操作;如需异步,应移交到独立任务队列或微任务中
注册与解绑必须严格配对
漏掉解绑是内存泄漏和崩溃的常见源头:
- Android Activity 在 onCreate 注册,onDestroy 必须 removeObserver
- Vue 组件在 onMounted 注册,onUnmounted 清理;React useEffect 返回清理函数
- 临时监听可用一次性观察者:update 执行后自动从主题中移除自身
- 避免在 notify 过程中增删 observer 列表(Java 可用迭代器安全删除,JS Set 不支持边遍历边删)
高频变更要加节制,多线程要加防护
真实场景中,状态可能每秒变几十次,不能每次都全量通知:
- 对连续快速变更做节流(throttle)或取最终值合并(debounce + latest-only)
- 多线程下 observer 列表的 add/remove/notify 需同步;推荐用不可变快照(如 Java 的 Collections.unmodifiableList 或 Kotlin 的 toList())
- 如需控制执行顺序(例如先更新 UI 再记日志),可在 observer 上加 priority 字段或分组管理
- JS 单线程但 Promise.then 或 setTimeout 会打破同步时序,通知 data 应带时间戳或版本号辅助判断新鲜度










