好多设计模式的书上说观察者模式又叫发布订阅模式,但是在面试的时候有的面试官却问两者有什么区别?那么非要说区别的话,就从基本的流程图上分析分析;

观察者模式

一个称为subject的对象维系着一系列关注着它的对象(称为observer),一旦subject状态发生改变就会通知这一系列的观察者对象们。这是一种一对多的模式。

发布/订阅模式

存在着这样一个中央控制中心,作为发布者的你,可以通过控制中心发消息给你的订阅者。发布者和订阅者之间没有联系。这是一种多对多的模式。

来看下二种模式的分析图:

代码实现:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 观察者模式
class Observer {
constructor(subject) {
this.subject = subject;
}

update (message) {
console.log(`订阅${this.subject}主题的客户:${message}`);
}
}

// 主题
class Subject {
constructor() {
this.subjects = {};
}

add(observer) {
let subject = observer.subject;
if (!this.subjects[subject]) {
this.subjects[subject] = [];
}
this.subjects[subject].push(observer);
}

remove(subject, observer) {
this.subjects[subject].forEach((item, index) => {
if (item === observer) {
this.subjects[subject].splice(index, 1);
}
})
}

notify(subject, message) {
this.subjects[subject].forEach((item) => {
item.update(message);
})
}
}

const observer1 = new Observer('雷佳音');
const observer2 = new Observer('雷佳音');
const observer3 = new Observer('雷佳音');
const observer4 = new Observer('张艺兴');
const observer5 = new Observer('张艺兴');
const observer6 = new Observer('张艺兴');
const observer7 = new Observer('张艺兴');
const observer8 = new Observer('鹿晗');

const subject = new Subject();

subject.add(observer1);
subject.add(observer2);
subject.add(observer3);
subject.add(observer4);
subject.add(observer5);
subject.add(observer6);
subject.add(observer7);
subject.add(observer8);

subject.notify('雷佳音', '你有新消息了,请及时查看!');
subject.notify('张艺兴', '你有新消息了,请及时查看!');
subject.notify('鹿晗', '你有新消息了,请及时查看!');

// 发布订阅模式
class EventBus {
constructor() {
this.subjects = {};
}

on(subject, callback) {
if (!this.subjects[subject]) {
this.subjects[subject] = [];
}
this.subjects[subject].push(callback);
}

off(subject, callback = null) {
if (callback === null) {
this.subjects[subject] = [];
} else {
this.subjects[subject].forEach((item, index) => {
if (item === callback) {
this.subjects[subject].splice(index, 1);
}
})
}
}

emit(subject, data = null) {
this.subjects[subject].forEach((item) => item(data));
}
}

const people = function (val) {
console.log(`生日礼物我收到啦, 是${val.gistName},我非常喜欢,谢谢你!`);
};

const bus = new EventBus();
bus.on('newItem', people);
const gift = {
gistName: '可爱熊'
};
bus.emit('newItem', gift);

二者之间的区别总结如下:

  • 观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
  • 发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
  • 察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
  • 观察者模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。

尽管它们之间有区别,但有些人可能会说发布-订阅模式是观察者模式的变异,因为它们概念上是相似的。

大概这些,over。