1、观察者模式
1.1、定义
观察者模式,即观察者监听被观察者的变化,被观察者发生改变时,通知所有的观察者。
其实,观察者模式就类似于事件的监听addEventListener,比如:
ele.addEventListener('click', () => {});
addEventListener就相当于注册了一个观察者,当观察到‘click’事件的时候,作出一些处理。
1.2、代码实现
// 举例:消费者订阅商店的商品推送信息
// 被观察者
class Subject {
constructor() {
this.observer = [] // 已订阅的观察者对象
}
// 顾客订阅商店的商品事件
subscribe(observer) {
this.observer.push(observer)
}
// 通知顾客
notify(msg) {
this.observer.forEach(ob => {
ob.getMessage(msg)
})
}
// 取消订阅
unsubscribe(observer){
this.observer = this.observer.filter(ob => ob !== observer);
}
}
// 观察者
class Observer {
constructor(name) {
this.name = name;
}
// 接受商店派发的消息
getMessage(goodsCount) {
console.log(`${this.name}收到消息了, ${goodsCount}`)
}
}
let subject = new Subject()
let o1 = new Observer('张三')
let o2 = new Observer('李四')
subject.subscribe(o1)
subject.subscribe(o2)
subject.notify('全场打8折了!') // 修改商品的数量,订阅者将收到消息
subject.unsubscribe(o1); // o1取消订阅
subject.notify('清空大甩卖了!') // 修改商品的数量,订阅者将收到消息
2、发布订阅模式
class EventEmitter {
constructor(maxListeners){
this.events = {};
// maxListeners 同一事件,监听的最大回调函数个数
this.maxListeners = maxListeners || Infinity;
}
emit(event,...args){
const cbs = this.events[event];
if(!cbs){
console.warn(`${event} event is not register!`)
return this;
}
cbs.forEach( cb => cb.apply(this,args));
return this;
}
on(event,cb){
if(!this.events[event]){
this.events[event] = []
}
if(this.maxListeners !== Infinity && this.events[event].length >= this.maxListeners){
console.warn(`${event} event has reached max listeners!`);
return;
}
this.events[event].push(cb);
return this;
}
once(event,cb){
const func = (...args)=>{
this.off(event,func);
cb.apply(this,args);
}
this.on(event,func);
return this;
}
off(event,cb){
if(!cb){
this.events[event] = null;
}else{
this.events[event] = this.events[event].filter(item=> item !== cb );
}
return this;
}
}
const add = (a,b) => console.log(a + b);
const log = (...args) => console.log(...args);
const event = new EventEmitter()
event.on('add',add);
event.on('log',log);
event.emit('add',1,2); // 3
event.emit('log','hi~'); // 'hi~'
event.off('add');
event.emit('add',1,2); // Error: add event is not register
event.once('once',add)
event.emit('once',1,2); // 3
event.emit('once',1,2); // Error: once event is not register
event.emit('once',1,2);
3、观察者模式与发布订阅模式的区别
观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心
。
3.1、具体区别如下
-
是否直接进行交互
观察者模式中观察者和目标直接进行交互
,
发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰
。 -
耦合程度 ----- 这是由于是否直接进行交互所引起的
在观察者模式中,由于它们之间是直接进行交互,所以组件之间强耦合
。
在发布订阅模式中,由于它们之间是通过调度中心进行处理,所以组件之间松耦合
。由于调度中心的存在,使得可以进行更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的消息订阅者都会接收到,这就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。
作者:snow_in
链接:https://www.jianshu.com/p/594f018b68e7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。