发布订阅模式和观察者模式

130 阅读2分钟

发布订阅模式

发布订阅这模式有三个主体:

发布主体:发布消息,也就是调用Event对象的emit()函数

订阅主体:订阅消息,使用on进行订阅,订阅的时候指定订阅处理函数fn

媒介主体:也就是Event对象,维护发布主体与订阅主体之间的关系,当订阅者订阅消息的时候,对订阅者的信息进行收集,保存到一个数组arr里面,当发布主体进行发布消息,也就是触发emit事件的时候,一次循环arr,循环所有的订阅者信息进行执行。这就实现了多个订阅者订阅同一消息,当消息发布的时候,所有的订阅者都会收到通知,即发布订阅模式。

const fs = require('fs');
var Event={
    arr:[],
    //订阅函数
    on(fn){
        this.arr.push(fn);
    },
    //发布消息,发布消息的时候粗发订阅者
    emit(data){
       this.arr.forEach(fn=>{
           fn(data);
       })
    }
}

Event.on(function(data){
  console.log("订阅者1收到信息:"+data)
})
Event.on(function(data){
    console.log("订阅者2收到信息:"+data)
})

fs.readFile('./a.txt', function (err, data) {
    if(!err){
        Event.emit(data.toString());
    }
});
fs.readFile('./b.txt', function (err, data) {
    if(!err){
        Event.emit(data.toString())
    }
});

执行结果:
订阅者1收到信息:{
  name:"sunshine",
  age:23
}
订阅者2收到信息:{
  name:"sunshine",
  age:23
}
订阅者1收到信息:{
  name:"mengfan",
  age:22
}
订阅者2收到信息:{
  name:"mengfan",
  age:22
}

观察者模式

观察者模式是基于发布订阅者模式的。

Subject为被观察者,被观察者通过调用setState来实现自身状态的改变,setState处理被观察者的数据之后,会通知所有的观察者,通过observers的forEach循环进行通知。

Observer为观察者,要与被观察者进行绑定,registerObserver提供了观察者与被观察者绑定的实现,这与发布订阅模式的on很类似。并且绑定的时候,被观察者要记录所有观察者的基本信息,保存在自己的属性observers数组中,

//被观察者
class Subject {
    constructor() {
        this.state={};
        this.observers=[];
    }
    registerObserver(observer){
        this.observers.push(observer);
    }
    setState(newState){
        this.state=newState;
        this.observers.forEach(observer=>{
            console.log(observer.name+"更新了")
            observer.update(newState);
        })
    }

}

//观察者
function  Observer(name){
    this.name=name;
    this.update=(newsTate)=>{
        console.log(newsTate);
    }
}
var subject=new Subject();
var observer=new Observer("观察者1");
var observer2=new Observer("观察者2");
subject.registerObserver(observer);
subject.registerObserver(observer2);
subject.setState({name:"更新状态1"});
subject.setState({name:"更新状态2"});

执行结果:
观察者1更新了
{ name: '更新状态1' }
观察者2更新了
{ name: '更新状态1' }
观察者1更新了
{ name: '更新状态2' }
观察者2更新了
{ name: '更新状态2' }

发布订阅模式和观察者模式的区别:

发布订阅模式和观察者模式之间的区别主要在于调度的地方不同。

发布订阅模式属于广义上的观察者模式

观察者和被观察者,是松耦合的关系 发布者和订阅者,则完全不存在耦合