代码实现
- 定义接口
// 主题接口
interface Subject {
addObserver(observer: Observer): void;
removeObserver(observer: Observer): void;
notifyObservers(): void;
}
// 观察者接口
interface Observer {
update(): void;
}
- 创建具体主题类
class ConcreteSubject implements Subject {
private observers: Observer[] = [];
private state: any;
public addObserver(observer: Observer): void {
this.observers.push(observer);
}
public removeObserver(observer: Observer): void {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
public notifyObservers(): void {
this.observers.forEach(observer => observer.update());
}
public setState(newState: any): void {
this.state = newState;
this.notifyObservers();
}
public getState(): any {
return this.state;
}
}
- 创建具体观察者类
class ConcreteObserver implements Observer {
private subject: Subject;
private name: string;
constructor(subject: Subject, name: string) {
this.subject = subject;
this.name = name;
this.subject.addObserver(this);
}
public update(): void {
console.log(`${this.name} 收到通知,主题状态为: ${this.subject.getState()}`);
}
}
- 使用示例
// 创建主题
const subject = new ConcreteSubject();
// 创建观察者
const observer1 = new ConcreteObserver(subject, '观察者1');
const observer2 = new ConcreteObserver(subject, '观察者2');
// 改变主题状态
subject.setState('新状态');
应用场景
- 事件驱动系统:在前端开发中,比如网页上的按钮点击、表单提交等事件,当事件发生(主题状态改变)时,相关的处理逻辑(观察者)会收到通知并执行。
- 数据绑定:当数据模型(主题)发生变化时,与之绑定的视图(观察者)需要更新以反映最新的数据。
优势
- 解耦主题和观察者:主题和观察者之间不需要相互了解细节,只通过接口进行交互,使得系统的扩展性和维护性更强。
- 提高可维护性:如果需要增加或移除观察者,只需要在主题类中进行简单的添加或移除操作,不会影响到其他部分的代码。
- 支持广播通信:主题可以同时通知多个观察者,实现一对多的关系,适用于需要同时通知多个对象的场景。