尽管观察者模式和发布订阅模式在某些方面相似,但它们在设计和使用上有一些关键的区别。以下是详细的对比:
- 使用示例
javascript
//观察者模式
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
removeObserver(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
}
notify(data) {
this.observers.forEach((observer) => observer.update(data));
}
}
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received data: ${data}`);
}
}
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notify('Hello Observers!');
// 输出: Observer 1 received data: Hello Observers!
// Observer 2 received data: Hello Observers!
js
//发布订阅模式
class EventEmitter {
constructor() {
this.events = {};
}
subscribe(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
unsubscribe(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName] = this.events[eventName].filter( (cb) => cb !== callback );
}
}
publish(eventName, ...args) {
if (this.events[eventName]) {
this.events[eventName].forEach((callback) => { callback(...args); });
}
}
}
const ee = new EventEmitter();
ee.subscribe('click', (arg) => {
console.log('click1' + arg);
});
ee.publish('click', 121212); // 输出: click1121212
- 定义和角色
- 观察者模式
-
核心角色:
Subject(主题):维护一个观察者列表,提供添加、删除观察者的方法,并在状态变化时通知所有观察者。
Observer(观察者):定义一个更新接口,当主题状态变化时,观察者通过该接口接收通知并进行相应处理
-
关系
观察者和主题之间存在直接的依赖关系。观察者需要知道主题的存在,并且主题需要知道观察者的具体接口
-
- 发布订阅模式
-
核心角色:
Publisher(发布者):发布事件或消息,但不需要知道订阅者的存在。
Subscriber(订阅者):订阅特定事件或消息,并在事件发生时接收通知。
Event Channel(事件通道:作为发布者和订阅者之间的中介,负责事件的分发。
-
关系
发布者和订阅者之间没有直接的依赖关系。发布者只需知道如何通过事件通道发布事件,而订阅者只需知道如何订阅和处理事件。
-
- 观察者模式
- 解耦成都
- 观察者模式
- 耦合度较高:主题需要知道观察者的具体接口(如
update
方法),观察者也需要知道主题的存在。 - 适用场景:适用于对象之间的关系相对固定且已知的情况
- 耦合度较高:主题需要知道观察者的具体接口(如
- 发布订阅模式
- 耦合度较低:发布者和订阅者之间通过事件通道进行通信,彼此不需要直接知道对方的存在。
- 适用场景:适用于需要高度解耦的系统,特别是在大型系统中,组件之间的依赖关系复杂时。
- 观察者模式
- 灵活性
- 观察者模式
- 灵活性有限:主题和观察者之间的关系是固定的,难以动态地添加或移除观察者。
- 适用场景:适用于简单的、关系固定的场景。
- 发布订阅模式
- 灵活性高:可以动态地添加或移除订阅者,事件通道可以处理多种类型的事件。
- 适用场景:适用于复杂的、需要动态管理的系统。
- 观察者模式