无需登录 数据私有 本地保存

观察者模式实验室 - 交互式学习设计模式

8
0
0
0

观察者模式实验室

交互式学习设计模式 —— 模拟股票行情推送场景,可视化观察者模式的通知机制

观察者:3 通知次数:0 当前模式:推模式 (Push)
📈 StockMarket
主题(Subject / 被观察者)
当前股价
$100.00
$
推模式:Subject 主动将数据推送给所有观察者
👀 观察者列表
Observers —— 订阅股票行情更新
暂无观察者,请添加至少一个观察者
📋 事件日志
0
暂无日志,尝试发布一次通知吧
常见问题 & 知识点

观察者模式是一种行为型设计模式,定义了一种一对多的依赖关系。当一个对象(Subject,主题/被观察者)的状态发生变化时,所有依赖于它的对象(Observer,观察者)都会得到自动通知并更新。这种模式广泛应用于事件处理、数据绑定、消息推送等场景。例如本工具模拟的股票行情推送:股价(Subject状态)变化时,所有订阅的显示设备(Observers)都会收到更新。

  • Subject(主题/被观察者):维护观察者列表,提供 attach()detach()notify() 方法。本工具中的 StockMarket 就是 Subject。
  • Observer(观察者接口):定义 update() 方法,供 Subject 在状态变化时调用。
  • ConcreteSubject(具体主题):实现 Subject,存储具体状态,状态变化时调用 notify()
  • ConcreteObserver(具体观察者):实现 Observer 接口,在 update() 中执行具体的更新逻辑。

推模型(Push):Subject 在通知时直接将数据作为参数传递给 Observer 的 update(data) 方法。优点是观察者无需再查询,缺点是可能传递了观察者不需要的数据。

拉模型(Pull):Subject 仅通知观察者状态已改变,观察者收到通知后,自行调用 Subject 的 getState() 方法获取所需数据。优点是观察者可以按需获取数据,缺点是需要额外查询。在本工具中可切换两种模式进行对比体验。

  • GUI事件处理:按钮点击、文本框变化等事件监听。
  • 数据绑定:Vue、React 等框架的响应式数据更新机制。
  • 消息队列/发布-订阅:RabbitMQ、Redis Pub/Sub。
  • 实时行情推送:股票、加密货币价格更新。
  • 日志系统:多个日志处理器同时监听日志事件。
  • 游戏开发:成就系统、UI更新响应游戏状态变化。

两者常被混淆,但关键区别在于:

观察者模式:Subject 和 Observer 直接耦合,Subject 维护 Observer 列表并直接调用其 update 方法。通信是同步的、点对点的。

发布-订阅模式:通过事件通道/消息代理(Event Channel/Broker)解耦,Publisher 和 Subscriber 互不知道对方存在。通信可以是异步的、广播式的。发布-订阅是观察者模式的一种变体和扩展

优点:
  • 实现了 Subject 和 Observer 之间的松耦合(抽象耦合)。
  • 支持广播通信,一对多通知。
  • 符合开闭原则,新增观察者无需修改 Subject 代码。
缺点:
  • 如果观察者过多,逐个通知可能耗时
  • 通知顺序可能不可控,可能引发循环依赖
  • 如果观察者处理不当,可能导致内存泄漏(未及时取消订阅)。

JavaScript 中观察者模式非常常见:

DOM事件监听element.addEventListener('click', callback) —— 元素是 Subject,回调是 Observer。

自定义实现:可以轻松用 ES6 Class 实现,如本工具所示。核心是维护一个 observers 数组,提供 attach/detach/notify 方法。

RxJS:提供了强大的 Observable/Observer 模式实现,支持异步数据流处理。

观察者模式是最常用的设计模式之一,理解它有助于:

✅ 更好地理解前端框架的响应式原理(Vue的响应式系统、React的state更新)。
✅ 设计事件驱动架构,编写更解耦、可维护的代码。
✅ 理解微服务间的消息通信模式。
✅ 为学习更复杂的模式(如发布-订阅、响应式编程)打下基础。