TypeScript实现观察者模式

观察者模式

观察者模式定义了一种一对多的关系,让多个订阅者对象同时监听某一个主对象,这个主对象的状态发生变化时就会通知所有观察自己的观察者(订阅者)对象。

特点

订阅者与发布者双方联系更紧密,发布者自己收集和维护观察者,并在状态变化时主动通知观察者更新。所以观察者模式的订阅者与发布者之间是存在依赖的
优势

降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
目标与观察者之间建立了一套触发机制。
缺点
目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

实现示例

定义发布者类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

运行结果
运行结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值