一、发布订阅模式
发布订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到状态改变的通知。
多方订阅,一方发布,订阅放会收到通知
举例:教学楼中每个教室都有一个广播器,例如甲同学进入了A教室,甲同学可以理解为订阅,A教室有着A教室的订阅者,当校长只对A教室的广播进行播放时,只有A教室的所有学生可以受到广播信息。
常见的发布订阅比如 Vue中eventBus的 $on - $emit
js实现一个发布订阅
<script>
// 发布订阅模式是一种对象间一对多的关系,当一个对象发生改变时,所有依赖于它的对象都能接收到状态的通知
// 定义eventBus
class eventBus {
// 存放所有订阅者的对象
clientList = {};
// 发布 (事件名称,参数)
$emit = function (event, params) {
// 循环调用订阅的所有callback
this.clientList[event].forEach((callback) => callback(params));
};
// 订阅 (事件名称,回调)
$on = function (event, callback) {
// 如果之前键不存在 ? {updata:[()=>{}]} : {updata:[()=>{},()=>{}]}
!this.clientList[event]
? (this.clientList[event] = [callback])
: this.clientList[event].push(callback);
};
}
// 创建eventBus实例对象
const events = new eventBus();
// 定于 updata的事件名称
events.$on("updata", (params) => {
console.log("updata1", params);
});
// 定于 updata的事件名称
events.$on("updata", (params) => {
console.log("updata2", params);
});
// 发布订阅
events.$emit("updata", "参数");
</script>
我们发现每次进行订阅、通知都是在使用events中的 clientList, 并不会直接用$on 和 $emit 发生关系。
二、观察者模式
观察者模式既一个对象被多个对象所依赖,当依赖的对象发生更新时,会自动通知所有依赖的对象。
观察者模式和发布订阅模式很相似,区别就是 发布订阅者模式会有一个调度中心去互相联系,而观察者模式 只有观察者和被观察者有直系的联系
举例:一家武校,有两位学生,两位学生为观察者,观察着老师的讲话及动作,老师就称为被观察者,老师一有变动,两位学生就能够观察到老师的变动。
// 定义观察者
class Teacher {
constructor (name){
this.name = name
// 存储观察者
this.students = []
}
// 添加观察者
addStu(student){
this.students.push(student)
}
// 删除观察者
delStu(student){
const idx =this.students.findIndex(it=>it==student)
idx!=-1?this.students.splice(idx,1):''
}
// 发送通知
notice(msg){
console.log(this.name+'老师说:'+msg);
this.students.forEach(it=>it.updata(msg))
}
}
// 定义被观察者
class Student {
constructor(name){
this.name = name
}
updata(msg){
console.log(this.name+'收到了老师说的:',msg);
}
}
const teacherMa = new Teacher('马保国')
const stuJia = new Student('甲')
const stuYi = new Student('乙')
teacherMa.addStu(stuJia)
teacherMa.addStu(stuYi)
teacherMa.delStu(stuYi)
teacherMa.notice('我要开始练拳了')
总结
发布订阅者模式和观察者模式都是一对多的关系,每次有新的通知,都会告知订阅者和观察者,最大的区别就是,发布订阅者中有一个调度中心来通知订阅者,而不是像观察者那样 直接通过被(目标)观察者来通知观察者。