前言
前段时间接了个外包赚了点小钱钱,就没有怎么更新博客,最近有时间了,继续更新博客。
概念
观察者模式定义了对象间的一种一对多的依赖关系,当对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯
发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者存在
好了好了,知道这上面描述的很官方,看下文吧
观察者模式
观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯
观察者模式就像是,CUIT(驾校)某一天我是说某一天,从双流一变成了双一流学校,那么所有学生的学历都从重本(驾校) -> 双一流
,那么CUIT(目标者)和所有的学生之间(观察者)就构成了一种一对多的依赖关系,这种关系也称为观察者模式
模式特征
- 一个目标者对象 Subject,拥有方法:添加 / 删除 / 通知 Observer;
- 多个观察者对象 Observer,拥有方法:接收 Subject 状态变更通知并处理;
- 目标对象 Subject 状态变更时,通知所有 Observer;
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class CUIT { constructor() { this.students = [] } addStudent(student) { this.students.push(student) } removeStudent(student) { this.students = this.students.filter((item) => item !== student) } notify() { this.students.forEach((student) => { student.update() }) } }
class Student { constructor(name) { this.name = name } update() { console.log(this.name + '的学历从驾校变成了双一流') } }
const cuit = new CUIT() const student1 = new Student('张三') const student2 = new Student('李四')
cuit.addStudent(student1) cuit.addStudent(student2) cuit.notify()
cuit.removeStudent(student2) cuit.notify()
|
发布-订阅模式
发布-订阅模式就像是,抖音(发布者)上有很多视频,但是不是一下子将所有的视频推送给你,而是将每个视频分好所属的类型,然后根据你的个人兴趣推送给你(订阅者)该类型的视频
模式特征
1.对象间功能解耦,弱化对象间的引用关系;
2.更细粒度地管控,分发指定订阅主题通知
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| class PubSub { constructor() { this.messages = {}; this.listeners = {}; } publish(type, content) { const existContent = this.messages[type]; if (!existContent) { this.messages[type] = []; } this.messages[type].push(content); } subscribe(type, cb) { const existListener = this.listeners[type]; if (!existListener) { this.listeners[type] = []; } this.listeners[type].push(cb); } notify(type) { const messages = this.messages[type]; const subscribers = this.listeners[type] || []; subscribers.forEach((cb, index) => cb(messages[index])); } }
class Publisher { constructor(name, context) { this.name = name; this.context = context; } publish(type, content) { this.context.publish(type, content); } }
class Subscriber { constructor(name, context) { this.name = name; this.context = context; } subscribe(type, cb) { this.context.subscribe(type, cb); } }
const TYPE_A = 'music'; const TYPE_B = 'movie'; const TYPE_C = 'novel';
const pubsub = new PubSub();
const publisherA = new Publisher('publisherA', pubsub); publisherA.publish(TYPE_A, 'we are young'); publisherA.publish(TYPE_B, 'the silicon valley'); const publisherB = new Publisher('publisherB', pubsub); publisherB.publish(TYPE_A, 'stronger'); const publisherC = new Publisher('publisherC', pubsub); publisherC.publish(TYPE_C, 'a brief history of time');
const subscriberA = new Subscriber('subscriberA', pubsub); subscriberA.subscribe(TYPE_A, res => { console.log('subscriberA received', res) }); const subscriberB = new Subscriber('subscriberB', pubsub); subscriberB.subscribe(TYPE_C, res => { console.log('subscriberB received', res) }); const subscriberC = new Subscriber('subscriberC', pubsub); subscriberC.subscribe(TYPE_B, res => { console.log('subscriberC received', res) });
pubsub.notify(TYPE_A); pubsub.notify(TYPE_B); pubsub.notify(TYPE_C);
|
区别
发布订阅模式更灵活,是进阶版的观察者模式,指定对应分发。
观察者模式维护单一事件对应多个依赖该事件的对象关系;
发布订阅维护多个事件(主题)及依赖各事件(主题)的对象之间的关系;
观察者模式是目标对象直接触发通知(全部通知),观察对象被迫接收通知。发布订阅模式多了个中间层(事件中心),由其去管理通知广播(只通知订阅对应事件的对象);
观察者模式对象间依赖关系较强,发布订阅模式中对象之间实现真正的解耦。
参考文献
https://vue3js.cn/interview/design/Observer%20%20Pattern.html#%E4%B8%89%E3%80%81%E5%8C%BA%E5%88%AB