文章目录
-
- 观察者模式(Observer Pattern)由被观察者和观察者组成,观察者可以是多个,被观察者维护着多个观察者,如添加或删除观察者;当被观察着数据变化时,会通过广播的方式通知维护的每一个观察者(即调用观察者提供的回调函数)。
- 观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知
- 小美通过自己的努力吸引了2个追求者.小美每次发朋友圈必定会得到两个追求者的回应.小美与两个追求者的关系形成了观察者模式.小美是被观察者,两个舔狗是观察者.小美发朋友圈这个动作会触发舔狗的回应 // 被观察者 class ABeautifulGirl { TIAN_GOU_LIST = [] // 舔狗们 // 添加观察者 attractTianGou(...tianGous) { Array.prototype.push.apply(this.TIAN_GOU_LIST, tianGous) } // 删除观察者 kickOffTianGou(tianGou) { const index = this.TIAN_GOU_LIST.indexOf(tianGou) this.TIAN_GOU_LIST.splice(index, 1) } // 女神技能:发朋友圈(发布通知) sendPost(data) { this.TIAN_GOU_LIST.forEach(tianGou => { tianGou.callback.call(tianGou, data) }) } } // 观察者 class TianGou { constructor(name, fn) { this.name = name this.lick = fn } callback(data) { console.log( `我是${this.name}今天女神发朋友圈说她${data},我要给女神发信息:` ) this.lick() } } // 定义两个观察者 const tiangou1 = new TianGou('tiangou1', () => { console.log('多喝热水') }) const tiangou2 = new TianGou('tiangou2', () => { console.log('请一定要多喝热水呀') }) // 小美通过自己的努力有了吸引别人关注的能力 const xiaomei = new ABeautifulGirl() xiaomei.attractTianGou(tiangou1, tiangou2) // 小美发了个朋友圈 xiaomei.sendPost('肚子疼')
- 舔狗舔了数次始终没有的到小美的青睐, 这次他学会了主动, 他准备再勾搭一个女神, 于是他想办法加了小丽的微信, 开始了同时对两人的观察. class ABeautifulGirl { constructor(name) { this.name = name } TIAN_GOU_LIST = [] sendPost(data) { console.log(`${this.name},发个朋友圈`) this.TIAN_GOU_LIST.forEach(tianGou => { tianGou.callback.call(tianGou, data) }) } } // 观察者:(主动)关注或取消关注 class TianGou { constructor(name, fn) { this.name = name this.lick = fn } subscribe(publish) { var sub = this var alreadyExists = publish.TIAN_GOU_LIST.some(function (item) { return item === sub }) // 如果女神的好友名单中没有这个人,则加入进去 if (!alreadyExists) publish.TIAN_GOU_LIST.push(sub) return this } unsubscribe(publish) { var sub = this publish.TIAN_GOU_LIST = publish.TIAN_GOU_LIST.filter(function (item) { return item !== sub }) return this } callback(data) { console.log( ` ${this.name} 看到女神发朋友圈说她 ${data} ,我要给女神发信息:` ) this.lick() } } // 小美 & 小丽 const xiaomei = new ABeautifulGirl('xiaomei') const xiaoli = new ABeautifulGirl('xiaoli') // 两个舔狗 const tiangou1 = new TianGou('tiangou1', () => { console.log(' 多喝热水') }) const tiangou2 = new TianGou('tiangou2', () => { console.log(' 请一定要多喝热水呀') }) // 舔狗主动订阅女神们的消息 tiangou1.subscribe(xiaomei).subscribe(xiaoli) tiangou2.subscribe(xiaomei) // 小美小丽肚子疼 xiaomei.sendPost('肚子疼') xiaoli.sendPost('腰子疼')
- 优点明显:降低耦合,两者都专注于自身功能; 缺点也很明显:所有观察者都能收到通知,无法过滤筛选;
- Publisher && Subscriber
- 舔狗们订阅了很多女神, 但大都无疾而终, 舔狗中有一只聪明狗, 姑且就叫它二哈吧, 二哈首先意识到, 女神们生病的时候只是发 [多喝热水] 是没有用的, 还要在早上对女神说早上好, 下班了对女生下班好, 去输液了要对女神说说输的的想你的夜. 二哈开始行动了, 于是二哈学习了发布订阅模式.
- 发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。 发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。
- const GirlsHub = function () { this.grils = {} this.on = function (name, cb) { if (this.grils[name]) { this.grils[name].push(cb) } else { this.grils[name] = [cb] } } this.trigger = function (name, ...arg) { if (this.grils[name]) { this.grils[name].forEach(eventListener => { eventListener(...arg) }) } } } let girls = new GirlsHub() girls.on('morring', () => { console.log('对小美说早安') }) girls.on('morring', () => { console.log('对小丽说早安') }) girls.on('morring', () => { console.log('对小美丽说早安') }) girls.on('noon', () => { console.log('对小美说午安') }) girls.on('noon', () => { console.log('对小丽说午安') }) girls.on('noon', () => { console.log('对小美丽说午安') }) girls.on('evening', () => { console.log('对小美说晚安') }) girls.on('evening', () => { console.log('对小丽说晚安') }) girls.on('evening', () => { console.log('对小美丽说晚安') }) girls.trigger('morring') girls.trigger('noon') girls.trigger('evening') 学会之后,二哈化被动为主动, 每到时辰就开始给女神们发消息, 本以为能够收获女神们的芳心,到后来发现,自己被一半人都拉黑了. 看来功力还不够深厚啊.需要学习以下其他的设计模式来优化以下方案。
- 优点:解耦更好,细粒度更容易掌控; 缺点:不易阅读,额外对象创建,消耗时间和内存
- 发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。 观察者模式维护单一事件对应多个依赖该事件的对象关系; 发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系; 观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象); 观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。
观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知,小美通过自己的努力吸引了2个追求者.小美每次发朋友圈必定会得到两个追求者的回应.小美与两个追求者的关系形成了观察者模式.小美是被观察者,两个舔狗是观察者.小美发朋友圈这个动作会触发舔狗的回应,
,舔狗舔了数次始终没有的到小美的青睐, 这次他学会了主动, 他准备再勾搭一个女神, 于是他想办法加了小丽的微信, 开始了同时对两人的观察.,
, 优点明显:降低耦合,两者都专注于自身功能; 缺点也很明显:所有观察者都能收到通知,无法过滤筛选;,Publisher && Subscriber,舔狗们订阅了很多女神, 但大都无疾而终, 舔狗中有一只聪明狗, 姑且就叫它二哈吧, 二哈首先意识到, 女神们生病的时候只是发 [多喝热水] 是没有用的, 还要在早上对女神说早上好, 下班了对女生下班好, 去输液了要对女神说说输的的想你的夜. 二哈开始行动了, 于是二哈学习了发布订阅模式.,发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。 发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。,
,学会之后,二哈化被动为主动, 每到时辰就开始给女神们发消息, 本以为能够收获女神们的芳心,到后来发现,自己被一半人都拉黑了.,看来功力还不够深厚啊.需要学习以下其他的设计模式来优化以下方案。, 优点:解耦更好,细粒度更容易掌控;, 缺点:不易阅读,额外对象创建,消耗时间和内存,发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。,观察者模式维护单一事件对应多个依赖该事件的对象关系;,发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;,观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。,
观察者模式(Observer Pattern)由被观察者和观察者组成,观察者可以是多个,被观察者维护着多个观察者,如添加或删除观察者;当被观察着数据变化时,会通过广播的方式通知维护的每一个观察者(即调用观察者提供的回调函数)。
观察者模式(Observer Pattern)由被观察者和观察者组成,观察者可以是多个,被观察者维护着多个观察者,如添加或删除观察者;当被观察着数据变化时,会通过广播的方式通知维护的每一个观察者(即调用观察者提供的回调函数)。
观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知
小美通过自己的努力吸引了2个追求者.小美每次发朋友圈必定会得到两个追求者的回应.小美与两个追求者的关系形成了观察者模式.小美是被观察者,两个舔狗是观察者.小美发朋友圈这个动作会触发舔狗的回应
// 被观察者
class ABeautifulGirl {
TIAN_GOU_LIST = [] // 舔狗们
// 添加观察者
attractTianGou(...tianGous) {
Array.prototype.push.apply(this.TIAN_GOU_LIST, tianGous)
}
// 删除观察者
kickOffTianGou(tianGou) {
const index = this.TIAN_GOU_LIST.indexOf(tianGou)
this.TIAN_GOU_LIST.splice(index, 1)
}
// 女神技能:发朋友圈(发布通知)
sendPost(data) {
this.TIAN_GOU_LIST.forEach(tianGou => {
tianGou.callback.call(tianGou, data)
})
}
}
// 观察者
class TianGou {
constructor(name, fn) {
this.name = name
this.lick = fn
}
callback(data) {
console.log(
`我是${this.name}今天女神发朋友圈说她${data},我要给女神发信息:`
)
this.lick()
}
}
// 定义两个观察者
const tiangou1 = new TianGou('tiangou1', () => {
console.log('多喝热水')
})
const tiangou2 = new TianGou('tiangou2', () => {
console.log('请一定要多喝热水呀')
})
// 小美通过自己的努力有了吸引别人关注的能力
const xiaomei = new ABeautifulGirl()
xiaomei.attractTianGou(tiangou1, tiangou2)
// 小美发了个朋友圈
xiaomei.sendPost('肚子疼')

舔狗舔了数次始终没有的到小美的青睐, 这次他学会了主动, 他准备再勾搭一个女神, 于是他想办法加了小丽的微信, 开始了同时对两人的观察.
class ABeautifulGirl {
constructor(name) {
this.name = name
}
TIAN_GOU_LIST = []
sendPost(data) {
console.log(`${this.name},发个朋友圈`)
this.TIAN_GOU_LIST.forEach(tianGou => {
tianGou.callback.call(tianGou, data)
})
}
}
// 观察者:(主动)关注或取消关注
class TianGou {
constructor(name, fn) {
this.name = name
this.lick = fn
}
subscribe(publish) {
var sub = this
var alreadyExists = publish.TIAN_GOU_LIST.some(function (item) {
return item === sub
})
// 如果女神的好友名单中没有这个人,则加入进去
if (!alreadyExists) publish.TIAN_GOU_LIST.push(sub)
return this
}
unsubscribe(publish) {
var sub = this
publish.TIAN_GOU_LIST = publish.TIAN_GOU_LIST.filter(function (item) {
return item !== sub
})
return this
}
callback(data) {
console.log(
` ${this.name} 看到女神发朋友圈说她 ${data} ,我要给女神发信息:`
)
this.lick()
}
}
// 小美 & 小丽
const xiaomei = new ABeautifulGirl('xiaomei')
const xiaoli = new ABeautifulGirl('xiaoli')
// 两个舔狗
const tiangou1 = new TianGou('tiangou1', () => {
console.log(' 多喝热水')
})
const tiangou2 = new TianGou('tiangou2', () => {
console.log(' 请一定要多喝热水呀')
})
// 舔狗主动订阅女神们的消息
tiangou1.subscribe(xiaomei).subscribe(xiaoli)
tiangou2.subscribe(xiaomei)
// 小美小丽肚子疼
xiaomei.sendPost('肚子疼')
xiaoli.sendPost('腰子疼')

优点明显:降低耦合,两者都专注于自身功能; 缺点也很明显:所有观察者都能收到通知,无法过滤筛选;
Publisher && Subscriber
舔狗们订阅了很多女神, 但大都无疾而终, 舔狗中有一只聪明狗, 姑且就叫它二哈吧, 二哈首先意识到, 女神们生病的时候只是发 [多喝热水] 是没有用的, 还要在早上对女神说早上好, 下班了对女生下班好, 去输液了要对女神说说输的的想你的夜. 二哈开始行动了, 于是二哈学习了发布订阅模式.
发布订阅模式:基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。 发布订阅模式与观察者模式的不同,“第三者” (事件中心)出现。目标对象并不直接通知观察者,而是通过事件中心来派发通知。
const GirlsHub = function () {
this.grils = {}
this.on = function (name, cb) {
if (this.grils[name]) {
this.grils[name].push(cb)
} else {
this.grils[name] = [cb]
}
}
this.trigger = function (name, ...arg) {
if (this.grils[name]) {
this.grils[name].forEach(eventListener => {
eventListener(...arg)
})
}
}
}
let girls = new GirlsHub()
girls.on('morring', () => {
console.log('对小美说早安')
})
girls.on('morring', () => {
console.log('对小丽说早安')
})
girls.on('morring', () => {
console.log('对小美丽说早安')
})
girls.on('noon', () => {
console.log('对小美说午安')
})
girls.on('noon', () => {
console.log('对小丽说午安')
})
girls.on('noon', () => {
console.log('对小美丽说午安')
})
girls.on('evening', () => {
console.log('对小美说晚安')
})
girls.on('evening', () => {
console.log('对小丽说晚安')
})
girls.on('evening', () => {
console.log('对小美丽说晚安')
})
girls.trigger('morring')
girls.trigger('noon')
girls.trigger('evening')
const GirlsHub = function () {
this.grils = {}
this.on = function (name, cb) {
if (this.grils[name]) {
this.grils[name].push(cb)
} else {
this.grils[name] = [cb]
}
}
this.trigger = function (name, ...arg) {
if (this.grils[name]) {
this.grils[name].forEach(eventListener => {
eventListener(...arg)
})
}
}
}
let girls = new GirlsHub()
girls.on('morring', () => {
console.log('对小美说早安')
})
girls.on('morring', () => {
console.log('对小丽说早安')
})
girls.on('morring', () => {
console.log('对小美丽说早安')
})
girls.on('noon', () => {
console.log('对小美说午安')
})
girls.on('noon', () => {
console.log('对小丽说午安')
})
girls.on('noon', () => {
console.log('对小美丽说午安')
})
girls.on('evening', () => {
console.log('对小美说晚安')
})
girls.on('evening', () => {
console.log('对小丽说晚安')
})
girls.on('evening', () => {
console.log('对小美丽说晚安')
})
girls.trigger('morring')
girls.trigger('noon')
girls.trigger('evening')

学会之后,二哈化被动为主动, 每到时辰就开始给女神们发消息, 本以为能够收获女神们的芳心,到后来发现,自己被一半人都拉黑了.
看来功力还不够深厚啊.需要学习以下其他的设计模式来优化以下方案。
优点:解耦更好,细粒度更容易掌控;
缺点:不易阅读,额外对象创建,消耗时间和内存
发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。
- 观察者模式维护单一事件对应多个依赖该事件的对象关系;
- 发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;
- 观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象);
- 观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。