1. 引言
观察者模式(Observer Pattern)和发布订阅模式(Publish-Subscribe Pattern)都是常见的设计模式,用于处理对象之间的依赖关系和通信。虽然它们在某些方面相似,但在实现方式和应用场景上存在显著差异。
2. 概述
2.1 观察者模式
观察者模式定义了一种一对多的依赖关系,当目标对象(Subject)的状态发生改变时,它的所有依赖者(Observers)都会被通知并自动更新。观察者模式通常用于事件驱动的系统,如用户界面的数据绑定、股票价格更新等。
核心角色:
- Subject(目标对象) :持有观察者的引用,当自身状态变化时,通知所有观察者。
- Observer(观察者) :当目标对象的状态变化时,主动获取目标对象的更新。
erDiagram
"目标对象" ||--o{ "观察者": "通知"
"观察者" }|..|{ "目标对象" : "观察"
2.2 发布订阅模式
发布订阅模式通过引入一个中介者(Event Center)来解耦发布者和订阅者之间的直接联系。发布者并不知道是否有订阅者,订阅者也不需要直接与发布者交互。事件中心处理消息的分发,使得发布者和订阅者能够独立工作。
核心角色:
- Publisher(发布者) :发布消息,但不关心是否有订阅者。
- Subscriber(订阅者) :关注特定事件的消息,并在事件发生时做出反应。
- Event Center(事件中心) :作为中介,负责消息的发布和分发,处理事件的订阅和取消订阅。
erDiagram
"发布者" ||--o{ "事件" : "触发"
"订阅者" ||--o{ "事件" : "监听"
"事件" ||--o{ "事件中心" : "管理"
3. 代码示例
观察者模式(Observer Pattern)
// 目标对象(Subject)
class Subject {
constructor() {
this.observers = [];
}
// 添加观察者
addObserver(observer) {
this.observers.push(observer);
}
// 移除观察者
removeObserver(observer) {
this.observers = this.observers.filter(o => o !== observer);
}
// 通知所有观察者
notify() {
this.observers.forEach(observer => observer.update());
}
}
// 观察者(Observer)
class Observer {
constructor(name) {
this.name = name;
}
// 接收通知的方法
update() {
console.log(`${this.name} 收到通知`);
}
}
// 使用示例
const subject = new Subject();
const observer1 = new Observer('观察者1');
const observer2 = new Observer('观察者2');
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notify();
// 输出:
// 观察者1 收到通知
// 观察者2 收到通知
发布订阅模式(Publish-Subscribe Pattern)
// 事件中心(Event Center)
class EventCenter {
constructor() {
this.events = {};
}
// 订阅事件
subscribe(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
// 发布事件
publish(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
// 取消订阅事件
unsubscribe(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
}
// 使用示例
const eventCenter = new EventCenter();
function subscriber1(data) {
console.log(`订阅者1 收到消息:${data}`);
}
function subscriber2(data) {
console.log(`订阅者2 收到消息:${data}`);
}
eventCenter.subscribe('news', subscriber1);
eventCenter.subscribe('news', subscriber2);
eventCenter.publish('news', '新消息发布');
// 输出:
// 订阅者1 收到消息:新消息发布
// 订阅者2 收到消息:新消息发布
主要区别:
-
耦合度:
- 观察者模式中,目标对象和观察者之间是直接关联的,目标对象需要维护观察者列表,观察者也需要知道目标对象的存在。
- 发布订阅模式通过引入事件中心,发布者和订阅者之间没有直接关联,解耦性更强。
-
角色数量:
- 观察者模式通常只有目标对象和观察者两个角色。
- 发布订阅模式引入了事件中心,增加了一个中介角色。
-
使用场景:
- 观察者模式适用于一对多的场景,如事件监听。
- 发布订阅模式适用于需要解耦的场景,如消息队列。