发布订阅者

1. 观察者模式

对象间的一对多依赖关系,一个对象状态发生改变,依赖于它的对象都将得到通知,并自动更新。 观察者模式属于行为模式,行为模式。行为模式关注的是对象之间的通讯,观察者模式是观察者与被观察者之间的通讯。

2. 订阅-发布模式

在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者。发面者和订阅者之间存在第三个组件,称为调度中心或事件通道。调度中心或事件通道,维持着发布者和订阅者间的联系,过滤所有发布者传入的消息并相应地分发给订阅者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class PubSub {
constructor() {
this.subscribers = [];
}

subscribe(topic, callback) {
let callbacks = this.subscribers[topic];
if (!callbacks) {
this.subscribers[topic] = [callback];
} else {
callbacks.push(callback);
}
}

publish(topic, ...args) {
let callbacks = this.subscribers[topic] || [];
callbacks.forEach(callback => callback(...args));
}
}

// 创建事件调度中心,为订阅者和发布者提供调度服务
let pubSub = new PubSub();
// A订阅了SMS事件(A只关注SMS本身,而不关心谁发布这个事件)
pubSub.subscribe('SMS', console.log);
// B订阅了SMS事件
pubSub.subscribe('SMS', console.log);
// C发布了SMS事件(C只关注SMS本身,不关心谁订阅了这个事件)
pubSub.publish('SMS', 'I published `SMS` event');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Subject {
constructor() {
this.observers = [];
}

add(observer) {
this.observers.push(observer);
}

notify(...args) {
this.observers.forEach(observer => observer.update(...args));
}
}

class Observer {
update(...args) {
console.log(...args);
}
}

// 创建观察者ob1
let ob1 = new Observer();
// 创建观察者ob2
let ob2 = new Observer();
// 创建目标sub
let sub = new Subject();
// 目标sub添加观察者ob1 (目标和观察者建立了依赖关系)
sub.add(ob1);
// 目标sub添加观察者ob2
sub.add(ob2);
// 目标sub触发SMS事件(目标主动通知观察者)
sub.notify('I fired `SMS` event');