前言
设计模式就好比设计师在设计宏伟建筑的设计稿,而发布-订阅模式就是在众多设计风格中的,一种风格。发布-订阅则模式通常是用来定义和处理一对多的依赖关系。
案例解析
最近小区门口新开了一个水果店,超市会有不定期活动,但是搞活动又是不定时的,很顾客就想享受优惠价格,所以有两个解决方案,第一时每天都往水果店跑一下看一看,其次是是水果店留下顾客电话号码,主动发送短信通知。这种场景下可以考虑发布和订阅的设计模式。
观察者模式VS发布-订阅模式
实际场景分析
浏览器中监听滚动事件,就用到了发布订阅模式
document.body.addEventListener('scroll',function(){
console.log('发布后触发的时间')
})
页面加载时订阅了scroll滚动事件,当触发了滚动事件之后会通知然后触发对应的回调
简单实现一个订阅发布对象
构建一个订阅发布类,包含订阅功能,和发布功能
- 场景1:顾客A,顾客B订阅了超市C的活动,然后超市发布活动时,通知A,B客户
class Event{
constructor(){
// 订阅列表
this.listenList = [];
}
/*
*1.订阅
*2.发布
*3.取消订阅
*/
// 订阅手柄
listen(fn){
// 收集订阅
console.log('开始监听了')
this.listenList.push(fn)
console.log(this.listenList,'监听列表----')
}
// 发布手柄
trigger(...argumnets){
for(let i = 0; i < this.listenList.length;i++){
this.listenList[i](...argumnets)
}
}
}
let event = new Event()
// 顾客A订阅
event.listen(function(msg,price){
console.log('A顾客',msg,price)
})
// 顾客B订阅
event.listen(function(msg,price){
console.log('B顾客',msg,price)
})
setTimeout(() => {
event.trigger('超市C活动开始啦','只要1毛钱')
},2000)
- 场景二:顾客A只想接收水果类优惠活动,顾客B只想接收蔬菜类活动,此时简单的订阅列表无法满足需求,需要将订阅类表分类,即this.listenList = [{'A活动':XXX,'B活动':XXX}],还有场景是顾客C想取消之前的订阅活动
class Event{
constructor(){
// 订阅列表
this.listenList = {};
}
/*
*1.订阅
*2.发布
*3.取消订阅
*/
// 订阅手柄
/**
* @param {*订阅事件名} key
* @param {*发布后触发的事件} fn
*/
listen(key,fn){
// 收集订阅
this.listenList[key] = fn;
}
// 发布手柄
/**
* @param {*通知的活动对象} key
* @param {...any} argumnets
*/
trigger(key,...argumnets){
if(!this.listenList[key]){
console.log('不存在事件'+ key,'没有订阅或被移除了')
return;
}
this.listenList[key](key,...argumnets)
}
// 取消订阅
remove(key){
delete this.listenList[key]
}
}
let event = new Event()
// 顾客A订阅
event.listen('fruits',function(key,msg,price){
console.log('A顾客',key + msg,price)
})
// 顾客B订阅
event.listen('vegetable',function(key,msg,price){
console.log('B顾客',key + msg,price)
})
setTimeout(() => {
event.trigger('fruits' ,'超市C活动开始啦','只要1毛钱')
},2000)
setTimeout(() => {
event.trigger('vegetable' , '超市C活动开始啦','只要1毛钱')
},4000)
setTimeout(() => {
event.remove('vegetable')
},5000)
setTimeout(() => {
event.trigger('vegetable' , '移除超市C活动开始啦','哈哈哈')
},6000)
总结
发布订阅模式优点:1.时间上解耦,2.对象之前解耦