直接 3W

观察者模式(Observer)

观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。

在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。

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
33
34
35
36
// 定义一个主体对象
class Subject {
constructor() {
this.Observers = [];
}
add(observer) {
//添加
this.Observers.push(observer);
}
remove(observer) {
//移除
this.Observers.filter((item) => item === observer);
}
notify() {
this.Observers.forEach((item) => {
item.update();
});
}
}
//定义观察着对象
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log(`my name is:${this.name}`);
}
}

//测试
let sub = new Subject();
let obs1 = new Observer("leaf111");
let obs2 = new Observer("leaf222");
sub.add(obs1);
sub.add(obs2);
sub.notify();

发布订阅模式(Publisher && Subscriber)

发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。

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
33
34
35
let pubSub = {
subs: [],
subscribe(key, fn) {
//订阅
if (!this.subs[key]) {
this.subs[key] = [];
}
this.subs[key].push(fn);
},
publish(...arg) {
//发布
let args = arg;
let key = args.shift();
let fns = this.subs[key];

if (!fns || fns.length <= 0) return;

for (let i = 0, len = fns.length; i < len; i++) {
fns[i](args);
}
},
unSubscribe(key) {
delete this.subs[key];
},
};

//测试
pubSub.subscribe("name", (name) => {
console.log(`your name is ${name}`);
});
pubSub.subscribe("gender", (gender) => {
console.log(`your name is ${gender}`);
});
pubSub.publish("name", "leaf333"); // your name is leaf333
pubSub.publish("gender", "18"); // your gender is 18

对比

如上图所示:

1、在观察者模式中,观察者是知道 Subject 的,Subject 一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。

2、在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。

3、观察者模式大多数时候是同步的,比如当事件触发,Subject 就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。