【设计模式】---观察者模式与发布订阅者模式
2022-10-08 本文已影响0人
DY_alley
一、观察者模式和发布订阅者模式之间的区别
0.png观察者模式中观察者和目标直接进行交互, 而发布订阅模式由统一的调度中心来进行处理。订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。观察者是一对多的关系状态
虽然两种模式都存在订阅者和发布者,但是观察者模式是由具体目标调度的,而发布订阅模式是由调度中心调度的。所以观察者模式的订阅者和发布者之间是存在以来的。而发布订阅模式则不会。
(观察者)订阅者和订阅目标是联系在一起的,当订阅目标发生改变时,逐个通知订阅者。我们可以用报纸期刊的订阅来形象的说明,当你订阅了一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社和订报纸的客户就是上面文章开头所说的“一对多”的依赖关系。
(发布订阅)举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。A就是发布者,你是订阅者,微博就是调度中心,你和A是没有直接的消息往来的,全是通过微博来协调的(你的关注,A的发布动态)
二、观察者
class Observer {
constructor(){}
update(val){}
}
class ObserverList {
constructor() {
this.observerlist = [];
}
add(observer) {
return this.observerlist.push(observer);
}
remove(observer) {
this.observerlist = this.observerlist.filter(item=>item !== observer);
}
count() {
return this.observerlist.length;
}
get(index) {
return this.observerlist[index];
}
}
class Subject {
constructor() {
this.observers = new ObserverList();
}
addObserver(observer) {
this.observers.add(observer);
}
removeObserver(observer) {
this.observers.remove(observer);
}
notify(...arg) {
let len = this.observers.count();
for(var i=0;i<len;i++) {
this.observers.get(i).update(...arg);
}
}
}
三、发布订阅
class EventBus {
constructor() {
this.handlers = {};
}
$on(type,fn) {
if(Reflect.has(this.handlers,type)) {
this.handlers[type] = [];
}
this.handlers[type].push(fn);
}
$emit(type,...params) {
if(!Reflect.has(this.handlers,type)) {
throw new Error('当前事件未注册');
}
this.handlers[type].forEach((cb)=>{cb(...params)});
}
$off(type,fn) {
if(!Reflect.has(this.handlers,type)) {
throw new Error('无效事件');
}
if(!fn) {
return Reflect.deleteProperty(this.handlers,type);
} else {
const index = this.handlers[type].findIndex((cb)=>cb === fn);
if(index === -1) {
throw new Error('无效事件');
}
this.handlers[type].splice(index,1); // 从列表事件中删除
if(!this.handlers[type].length) { // 如果这个事件列表中没有事件了,则删除该事件
return Reflect.deleteProperty(this.handlers,type);
}
}
}
}