前言
设计模式可以说是反反复复看了很多遍,从懵懂到现在在代码中经常使用,其实最重要的是设计模式里面的思想,不要被高大上的名字所唬住,在这里复习一下观察者模式和发布订阅模式。
观察者模式
一个简单场景:产品经理提新需求,搬砖侠勤奋搬砖
// Publisher 添加移出观察者,通知观察者干啥
class Publisher {
observers = [];
add(observer) {
this.observers.push(observer);
}
remove(observer) {
this.observers.splice(this.observers.findIndex(item => item === observer) >>> 0, 1);
}
// 通知所有的观察者给爷干活
notify() {
this.observers.forEach(observer => {
observer.work(this);
});
}
}
// Observer
class Observer {
work(publish) {
console.log('接收到publish的指令');
}
}
// 实例
class PM extends Publisher {
prd = null;
setPrd(prd) {
this.prd = prd;
// 产品经理搞好了prd就开始通知搬砖侠开始干活
this.notify();
}
getPrd() {
return this.prd;
}
}
class BZX extends Observer {
constructor(name) {
super();
this.name = name;
}
work(pm) {
const prd = pm.getPrd();
console.log(`${this.name}收到了你的prd: ${prd}, 别催了一会就干~`);
}
}
// 测试:一个pm和三个搬砖侠的故事
let pm = new PM();
let bzx1 = new BZX('bzx1');
let bzx2 = new BZX('bzx2');
let bzx3 = new BZX('bzx3');
pm.add(bzx1);
pm.add(bzx2);
pm.add(bzx3);
pm.setPrd('给爷去搬砖!!!!');
// bzx1收到了你的prd: 给爷去搬砖!!!!, 别催了一会就干~
// bzx2收到了你的prd: 给爷去搬砖!!!!, 别催了一会就干~
// bzx3收到了你的prd: 给爷去搬砖!!!!, 别催了一会就干~
发布-订阅模式
用过 vue 的朋友应该很清楚,在 vue 中跨组件通信的方法有一种叫做 EventBus,是典型的发布-订阅模式。
简单实现一个发布-订阅。
class EventCenter {
// 事件调度中心
eventMap = {};
// 监听; 事件名和对应的回调函数
on(eventName, callback) {
if (typeof callback !== 'function') {
throw new Error('请设置正确的函数作为回调');
}
// 没有该eventName的事件队列就新建该队列
if (!this.eventMap[eventName]) {
this.eventMap[eventName] = [];
}
// 把callback放入队列
this.eventMap[eventName].push(callback);
}
// 触发;
emit(eventName, params) {
if (this.eventMap[eventName]) {
this.eventMap[eventName].forEach((callback, index) => {
callback(params);
});
}
}
off(eventName, callback) {
if (this.eventMap[eventName]) {
this.eventMap[eventName].splice(this.eventMap[type].indexOf(callback) >>> 0, 1);
}
}
}
// 测试:简单的事件
handleTest = params => {
console.log(`你好:${params.name}`);
};
const eventCenter = new EventCenter();
eventCenter.on('test', handleTest);
eventCenter.emit('test', { name: '94yk' });
// 输出:你好:94yk
差异
- 在观察者模式中,观察者是知道发布者的,发布者一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者互相不知道对方的存在。它们通过调度中心进行通信。
- 在发布订阅模式中,组件是松耦合的,正好和观察者模式相反。
- 观察者模式大多数时候是同步的,比如当事件触发,发布者就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。