这两个模式很容易弄混,很容易让人觉得这两个模式是相同的。但是首先我们要知道的是,这两个模式是不同的。硬要说相同的话,那也是广义上的相同(后面下文解释)。我们先来各自看看这两种模式,最后再搞清楚这两者间的联系与区别。
观察者模式
概念
是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。
简单来说,观察者模式就是,一个对象(被观察者)的状态发生改变时,会通知所有依赖它的对象(观察者),这两者是直接关联的。

举一个栗子
我们去餐厅吃饭的时候,经常会遇到需要排队的时候。我们可以把餐厅看作时被观察者,把排队的客人(拿号排队)看作是观察者。当餐厅有位置的时候,餐厅会出来通知排队的客人,到100号桌吃饭啦。这时排队的客人们都会看看自己手上的号,确定是否到自己吃饭了。
实现
const Subject = (() => {
const observers = [];
const addOb = (ob) => {
observers.push(ob);
};
const notify = () => {
for (let ob of observers) {
if (typeof ob.update === 'function') {
ob.update();
}
}
};
return {addOb, notify};
})();
let subA = {
update: () => {
console.log('updateSubA');
}
},
subB = {
update: () => {
console.log('updateSubB');
}
};
Subject.addOb(subA); //添加观察者subA
Subject.addOb(subB); //添加观察者subB
Subject.notify(); //通知所有观察者

订阅发布模式
概念
是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。
发布者状态更新时,发布某些类型的通知,只通知订阅了相关类型的订阅者。发布者和订阅者之间是没有直接关联的。

举一个栗子
还是以餐厅排队吃饭为例。这次我们拿了号后,不再傻傻地在餐厅门口等待。我们扫了一下排队二维码,我们在排队的过程中就可以去干其他事情了,因为到我们的号时,餐厅会发送一个通知给我们。
实现
const PubSub = (() => {
const topics = {}; //保存订阅主题
const subscribe = (type, fn) => { //订阅某类型主题
if (!topics[type]) {
topics[type] = [];
}
topics[type].push(fn);
};
const publish = (type, ...args) => { //发布某类型主题
if (!topics[type]) {
return;
}
for (let fn of topics[type]) { //通知相关主题订阅者
fn(args);
}
};
return {subscribe, publish};
})();
let subA = {type: 'event1'},
subB = {type: 'event2'},
subC = {type: 'event1'};
PubSub.subscribe(subA.type, () => console.log(`update eventType: ${subA.type} subA`)); //订阅者A订阅topic1
PubSub.subscribe(subB.type, () => console.log(`update eventType: ${subB.type} subB`)); //订阅者B订阅topic2
PubSub.subscribe(subC.type, () => console.log(`update eventType: ${subC.type} subC`)); //订阅者C订阅topic1
PubSub.publish(subA.type); //发布topic通知,通知订阅者A、C

联系与区别
联系
广义上来说,观察者模式和发布-订阅模式,都是一个对象的状态发生变化,通知相关联的对象。所以广义上来说,这两种模式是相似的,正如《Head First设计模式》所说。
发布 + 订阅 = 观察者模式
区别

- 观察者模式中,被观察者(可理解为发布者)与观察者(可理解为订阅者),这两者之间是直接关联、互相依赖的。而发布-订阅模式中,发布者与订阅者是不直接关联的,它们之间多了一个事件通道,通过这个事件通道把发布者和订阅者关联起来。
- 观察者模式中,被观察者发布通知,所有观察者都会收到通知。发布-订阅模式中,发布者发布通知,只有特定类型的订阅者会收到通知。
- 观察者模式中,被观察者发出状态更新通知后,观察者调用自身内部的更新方法。发布-订阅模式中,订阅者的更新是通过事件通道进行细节处理和响应更新的。
图片来源:MSDN
本文旨在互相学习,本文属个人理解,有说的不对的地方,师请纠正。转载请注明原帖。