观察者模式
-
设计理念是什么: 定义对象的一种一对多的依赖的关系,当一个对象发生改变时,所有依赖该对象的对象都得到通知并触发更新
-
解决了什么问题:一个对象状态改变给其他对象通知,易用、低耦合、保证高度的协作。
简单实现
假如我找商家订了送牛奶服务,那么每天有新牛奶的时候,商家都会给我送牛奶
// 定义一个数组
const observers = [];
const sub = {
// 新增
add: (observer) => {
observers.push(observer);
},
// 删除
remove: (observer) => {
for(var i = 0;i < observers.length;i++){
if(observers[i] === observer){
observers.splice(i,1);
}
}
},
// 发布
notify: () => {
for(var i = 0;i < observers.length;i++){
observers[i].update();
}
}
}
function Observer(text){
this.text = text;
}
Observer.prototype = {
update:function(){
console.log(this.text, '。。。');
}
}
var obs1 = new Observer('我爱喝纯奶');
var obs2 = new Observer('我爱喝兽奶');
//建立关系
sub.add(obs1);
sub.add(obs2);
// 发布
sub.notify();
发布订阅模式
24种基本的设计模式中并没有发布订阅模式,他只是观察者模式的别称,但是经过长时间的沉淀,它变得强大了起来,独立于观察者模式,我觉得发布订阅模式是根据观察者演化而来,相当于在观察者的基础上做了优化。
-
设计理念是什么: 与观察者模式相同
-
解决了什么问题:通过调度中心维持维持订阅者与发布者的的联系,使其完全解耦,过滤所有发布者传入的消息,并相应的发送他们给订阅者。
简答实现
// 我要收集游戏后的结果,当一个游戏结束时有相应的结果反馈
const allList = {};
const pubSub = {
add:(key,fn) => {
if (!allList[key]) {
allList[key] = [];
}
allList[key].push(fn);
},
notify: (type, value) => {
let fns = allList[type];
if(!fns || fns.length<=0) return false;
fns.forEach((item) => {
item(value)
})
},
delete: (key) => {
delete allList[key];
}
};
pubSub.add('英雄联盟', (text) => {
console.log(text + '-gap');
});
pubSub.add('云顶之弈', (text) => {
console.log(text + '出局');
});
// 游戏输了 上路差距
pubSub.notify('英雄联盟', 'top');
// 下棋输了 第八出局
pubSub.notify('云顶之弈', '第八');
对比
相同点
- 观察者与发布订阅模式都实现了当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新
不同点
- 观察者模式是观察者直接观察目标对象,没有中间层,而订阅发布模式则是多了调度中心,发布者和订阅者依赖调度中心,并不直接通信