观察者模式
这个模式在我看来原理就是发布者身上放着一个电话本(list)存着订阅者的l联系方式(回调函数),在触发条件(发布)后就会依次联系(遍历调用list中的回调函数)订阅者
上代码:
function Hunter(name){
this.name = name
this.list = []
}
// 发布消息方法
Hunter.prototype.publish = function(money){
console.log(`${this.name}发布了任务,赏金为${money}`)
this.list.forEach(item =>{
item(money)
})
}
//订阅,传入回调函数并存入到hunter的订阅数组中
Hunter.prototype.observe = function(fn,hunter){
console.log(`${this.name}订阅了${hunter.name}`)
hunter.list.push(fn)
}
let xiaoming = new Hunter('小明');
let xiaohua = new Hunter('小花')
xiaohua.observe((money) => {
console.log("小花接受了任务")
if(money < 500){
console.log(`并吐槽了一句:才${money}块`)
}
},xiaoming)
xiaoming.publish(500)
发布订阅模式
我觉得发布订阅模式是观察者模式的升级版,还是存放多个联系方式,但是在有消息发布时只通知订阅了该消息的人。更像是猎人——猎人酒吧——猎人 的关系
let hunterBar = { //定义一个猎人酒吧
missions: {},
//当有人订阅任务后missions的结构应为{
// tiger:[fn1,fn2,fn3]
// bear:[fn1,fn2]
// }
//酒吧提供订阅服务,订阅时得'填表'提供订阅人姓名、订阅的项目、有任务发布时的联系方式(回调函数)
observe: function (name, mission, fn) {
if (!this.missions[mission]) {
this.missions[mission] = []
}
this.missions[mission].push(fn)
console.log(`${name}订阅了有关${mission}的任务`)
},
//酒吧提供发布任务服务,发布时提供发布人的姓名、发布的任务、任务赏金
publish: function (name, mission, money) {
console.log(`${name}发布了关于${mission}的任务`)
//如果没人订阅过相关任务就不给发布
if (!this.missions[mission]) {
return false
}
//有人订阅过相关任务就挨个联系他们(调回调函数)
this.missions[mission].forEach(item => {
item(mission, money)
});
}
}
//定义猎人模板,只保存猎人的名字
function Hunter(name) {
this.name = name
console.log(`猎人${name}诞生了`)
}
//定义猎人订阅行为
Hunter.prototype.observe = function (mission, fn) {
//去酒吧订阅
hunterBar.observe(this.name, mission, fn)
}
//定义猎人发布行为
Hunter.prototype.publish = function (mission, money) {
//去酒吧发布
hunterBar.publish(this.name, mission, money)
}
let xiaoming = new Hunter('小明')
let xiaohua = new Hunter('小花')
let xiaoguang = new Hunter('小光')
xiaoming.observe('tiger', (mission, money) => {
console.log(`小明接受了${mission}任务,并表示又可以赚${money}块钱了`)
})
xiaohua.observe('tiger', (mission, money) => {
if(money < 1000){
console.log('小花觉得钱太少了不想接这个任务')
return false
}
console.log(`小花接受了${mission}任务,并表示又可以赚${money}块钱了`)
})
xiaoguang.publish('tiger', 500)