TS行为型设计模式之观察者模式

定义

Define a one-to-many dependency between objects so that when one object change state,all its dependents are notified and updated automatically.
(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新)

实现代码

//具体的观察者
class Observer {
    public update(info:any){
        //...some code
        console.log(`收到${info},更新`);
    }
}

//具体的被观察者
class Subject {
    private observerList = new Array<Observer>();

    public addObserver(obs:Observer){
        this.observerList.push(obs);
    }

    public deleteObserver(obs:Observer){
        let index = this.observerList.findIndex((val)=>{
            return val===obs;
        });
        index>-1&&this.observerList.splice(index,1);
    }

    public notify(info:any){
        for (const obs of this.observerList) {
            try {
                obs.update(info);
            } catch (error) {
                console.error(error);
            }
        }
    }
}

与事件总线的区别

事件总线是基于事件进行发布/订阅的,是多对多,存在中间者管理事件队列,发布者和订阅者解耦。前端最常见的点击事件监听就是如此设计。
TS行为型设计模式之观察者模式_第1张图片

观察者模式是基于对象进行发布/订阅的,是一对多,观察者和被观察者松耦合。
TS行为型设计模式之观察者模式_第2张图片

事件总线的实现

class EventBus{
    private eventList:{
        [prop: string]: Function[]
    } = {};

    public addEventListener(eventName:string,lis:Function){
        const thisEvent = this.eventList[eventName]||[];
        thisEvent.push(lis);
        this.eventList[eventName] = thisEvent;
    }

    public removeEventListener(eventName,lis:Function){
        const thisEvent = this.eventList[eventName];
        if(thisEvent){
            let index = thisEvent.findIndex((val)=>{
                return val===lis;
            });
            index>-1&&thisEvent.splice(index,1);
        }
    }

    //真正的发布者通过这个方法通知订阅者
    public needUpdate(eventName:string,info:any){
        const thisEvent = this.eventList[eventName];
        if(thisEvent){
            for (const lis of thisEvent) {
                lis.call(this,info);
            }
        }
    }
}

应用场景的区别

它们都常作触发(通信)机制,比如说被观察者类状态变了,通知观察者重新计算更新自己。

观察者模式一对多,比较专注,一般用于独立的局部通信,比如架构中单层或单应用内部通信。也可以用消息队列把多个联合起来,可以看下Vue的数据双向绑定的实现。

事件总线可多对多,比较灵活方便,一般作用于多种事件的全局通信,比如DOM事件监听、跨服务通信。

区别没有那么大,观察者模式比较独立,用消息队列把多个联合起来,就有了中间层,就很像事件总线了。

【参考文章】

  1. Observer vs Pub-Sub pattern

你可能感兴趣的:(设计模式)