推荐答案
// www.javascriptcn.com code example
class Subject {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
unsubscribe(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 update: ${data}`);
}
}
// Example Usage
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('New data available!');
subject.unsubscribe(observer2);
subject.notify('Another update!');本题详细解读
观察者模式是一种行为型设计模式,它允许一个对象(称为主题或可观察对象)维护一个依赖项列表(称为观察者),并在主题状态发生变化时自动通知这些依赖项。
核心概念
主题 (Subject/Observable):
- 维护一个观察者列表。
- 提供
subscribe(或attach) 方法,用于添加观察者到列表。 - 提供
unsubscribe(或detach) 方法,用于从列表移除观察者。 - 提供
notify方法,当主题状态发生变化时,遍历观察者列表并通知每个观察者。
观察者 (Observer):
- 定义一个
update方法,当主题状态发生变化时会被调用。 - 每个观察者都订阅了主题,以便接收通知。
- 定义一个
实现步骤
创建 Subject 类:
- 使用构造函数初始化
observers数组。 - 实现
subscribe方法,接受一个观察者实例并添加到observers数组。 - 实现
unsubscribe方法,接受一个观察者实例并从observers数组中移除。 - 实现
notify方法,遍历observers数组,并调用每个观察者的update方法。
- 使用构造函数初始化
创建 Observer 类:
- 构造函数中可以接收一个
name标识观察者 - 实现
update方法,该方法在被主题通知时执行,接受主题传递的数据。
- 构造函数中可以接收一个
使用示例:
- 创建一个
Subject实例。 - 创建多个
Observer实例。 - 使用
subscribe方法将观察者添加到主题的观察者列表中。 - 使用
notify方法触发通知。 - 使用
unsubscribe方法移除观察者。
- 创建一个
优势
- 松耦合: 主题和观察者之间解耦,主题不需要知道观察者的具体实现。
- 扩展性: 可以很容易地添加新的观察者,而无需修改主题的代码。
- 可重用性: 主题和观察者都可以在不同的场景下复用。
- 易于维护: 由于组件之间的解耦,代码更容易维护和理解。
使用场景
- 事件处理: 当发生特定事件时,需要通知多个监听者。
- 用户界面: 当模型数据发生变化时,需要更新视图。
- 消息队列: 当有新消息时,需要通知订阅者。
- 实时数据更新: 股票行情更新,社交媒体通知等。
注意点
- 内存泄漏: 如果观察者没有及时取消订阅,可能会导致内存泄漏。
- 通知顺序: 观察者的通知顺序可能不是固定的,如果顺序很重要,需要做特殊处理。
- 性能: 当观察者数量过多时,
notify方法的性能可能会受到影响,需要优化。