Introduction
观察者模式是设计模式中非常重要的一个模式,它属于行为模式的一种。下面是wikipedia中对观察者模式的定义。
In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
是不是看得一头雾水?我们先以一个现实中的例子来解释观察者模式。假设你现在正在看一场球赛,那么这时候你是观察者(Observer),而比赛是被观察者(Observable),或者叫主题(Subject)。比赛中如果你支持的球队进球了,你会欢呼跳跃,而如果对方进球,你会沮丧失望。你的状态会根据比赛的状态而改变,这就是观察者模式的一个例子。
观察者模式有以下特征:
- Subject和观察者之间是一对多的关系。
- 每个观察者有一个
update
方法。 - Subject(被观察者)维护一个观察者列表。
- 当Subject状态发生变化时,对于列表中每个观察者,都会调用它们的
update
方法通知他们。
Define Observer
下面的代码为每个观察者指定一个名字,当Subject发生变化时,Observer
的update
方法会被调用,打印出观察者的名字。update
方法就是被观察者和观察者联系的纽带。
1 | export default class Observer { |
Define Subject
Subject中文翻译为主题,它是一个对象,拥有注册观察者、删除观察者、通知观察者的方法。当某个特定事件发生时,Subject会通知所有观察者,让它们做出相应的反应。所以Subject实际上就是被观察者。
下面的代码为Subject添加了一个观察者数组,当Subject发生变化时,会遍历观察者数组,调用每个观察者的update
方法。subscribe
方法实际上就是addObserver
方法,unsubscribe
方法实际上就是removeObserver
方法。这两个方法用来将观察者加入或者移除观察者数组。被移除数组的观察者无法再收到Subject
的通知。
1 | import Observer from './Observer'; |
Use Observer
1 | import Observer from './Observer'; |
在 // 1 处,输入如下内容。
1 | Observer 1 updated |
在 // 2 处,输入如下内容,因为Observer 1被移除了,所以只有Observer 2和Observer 3收到了通知。
1 | Observer 2 updated |
Summary
- Subject(被观察者,也叫Observable):拥有注册观察者、删除观察者、通知观察者的方法。
- Observer(观察者):拥有update方法,当Subject发生变化时,Observer的update方法会被调用。
- 观察者和被观察者之间是松耦合的,被观察者只知道观察者的接口,而不知道观察者的具体实现。
网上常见的EventBus就是基于观察者模式实现的,当一个组件发生变化时,EventBus会通知所有订阅了这个事件的组件。下面是一个简单的EventBus实现。之所以将EventBus挂在到Window对象上,是因为这样可以在全局范围内使用EventBus。比如在不同的模块中,可以通过EventBus来通信。Module Federation中Remote模块和Host模块之间的通信也可以通过EventBus实现。
1 | // eventBus.js |
1 | // Emit an event from Remote module. |
1 | // Listen for an event from Host module. |
注意上面这个写法并不支持粘性事件,如果要支持粘性事件,该如何改进呢?