Z

观察者模式(Observer Pattern)

Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.

观察者模式对于前端来说,可算是最高频的设计模式了,在各种面试题中层出不穷。它还有一种称呼,名为“发布订阅模式”。与这两者类似的还有前端中的事件机制,这三者好像很相似,但似乎也有些区别。

从正儿八经的设计模式角度理解,观察者模式才是设计模式,观察者模式观察一个对象的变化,同时他还能接收对象变化的回调,当被观察的对象发生变动时,所有注册在其上的回调函数都会被调用。在前端中从概念角度讲属于观察者模式的有:

  • MutationObserver
  • IntersectionObserver
  • ResizeObserver
  • ReportingObserver
  • PerformanceObserver

这五种浏览器API才才是概念上的“观察者模式”,他们均接受回调函数,并可以指定观察对象。纯观察者模式非常好实现,核心就是监听对象的变化,所以直接用Proxy即可实现。观察者模式典型的使用方法是:

1const ob = new Observer(function () {
2    console.log('fire')
3});
4
5ob.observe(target);

但我们平常开发中使用最多的并不是概念上的观察者模式,而是事件机制,或者说是发布订阅模式。这种机制会根据特定的消息触发回调,典型的就是前端的事件机制。他们的典型使用方法是:

1const ev = new EventBus();
2
3ev.addEventListener('event a', function () {
4    console.log('event a fired')
5})
6
7ev.fire('event a')

事件机制(发布订阅模式)与观察者模式核心区别有两个:

  • 前者通过某一消息触发,而观察者模式通过被观察的对象变化触发
  • 前者有一消息中转地,在本例中就是EventBus,而观察者模式直接通过观察者本身触发。

所以观察者模式与发布订阅模式并不能混为一谈,从概念到实现上均有不同。