观察者模式
观察者模式
定义了一种一对多的关系,让多个订阅者对象同时监听某一个主对象,这个主对象的状态发生变化时就会通知所有观察自己的观察者(订阅者)对象。
特点
订阅者与发布者双方联系更紧密,发布者自己收集和维护观察者,并在状态变化时主动通知观察者更新。所以观察者模式的订阅者与发布者之间是存在依赖的
优势
降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
目标与观察者之间建立了一套触发机制。
缺点
目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
实现示例
定义发布者类ConcreteSubject 和观察者(订阅者)类RealizeObserver
ConcreteSubject
add,remove主要是添加和移除观察者
notify 主要是通知数组observers中所有的观察者对象的
changName用于改变主对象名称,同时在改变名称之后通知所有观察者
RealizeObserver
在RealizeObserver中必须有接收主对象通知的方法(这里定义为update)
TypeScript代码实现
//发布者
interface Subject {
name: string;
observers: Observer[]; //观察者数组
add(observer: Observer): void;// 添加观察者
remove(observer: Observer): void;// 移除观察者
notify(): void;// 通知所有观察者
changName(name: string): void //改变name
}
//观察者
interface Observer {
name: string;
//对发主对象发出的更新消息作出回应
update(subject: Subject): void;
}
// 定义主对象(发布者)类
class ConcreteSubject implements Subject {
public name: string = ''
public observers: Observer[] = []
constructor(name: string) {
this.name = name;
}
/**
* @Author: guoang
* @description: 增加观察者
* @param {Observer} observer 观察者
*/
public add(observer: Observer) {
console.log('增加观察者')
this.name = observer.name
this.observers.push(observer)
}
/**
* @Author: guoang
* @description: 移除观察者
* @param {Observer} observer 观察者
*/
public remove(observer: Observer) {
console.log('移除观察者')
this.observers = this.observers.filter(item => item !== observer)
}
// 通知所有观察者
public notify() {
console.log('通知所有观察者')
this.observers.forEach((observer: Observer) => {
observer.update(this)
})
}
/**
* @Author: guoang
* @description: 改变名称
* @param {string} name 要改变的名称
*/
public changName(name: string) {
this.name = name
this.notify()
}
}
//具体观察者(订阅者)类的简单实现
class RealizeObserver implements Observer {
public name: string = '猫'
constructor(name: string) {
this.name = name;
}
/**
* @Author: guoang
* @description: 对主对象的一个响应
* @param {ConcreteSubject} subject 主对象
*/
public update(subject: ConcreteSubject) {
console.log(`${this.name}----观察到目标名称发生改变,新名称----${subject.name}`);
}
}
const subject: ConcreteSubject = new ConcreteSubject('name');
const cat: RealizeObserver = new RealizeObserver('猫');
subject.add(cat);
const dog: RealizeObserver = new RealizeObserver('狗');
subject.add(dog);
const monkey: RealizeObserver = new RealizeObserver('猴');
subject.add(monkey);
subject.changName('新name')//改变名称会通知所有订阅者
subject.remove(cat);//取消cat的观察
subject.changName('新name2')//此时不会通知cat
运行结果