观察者模式
当Subject(被观察对象)状态发生变化时,会给所有的Observers(观察者们)发送一个通知函数,观察者们接收到通知后通常会调用各自的更新函数。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。
代码样例:
const Sub = function(...obrs) {
// 这个被观察的对象,收录着被哪些观察者观察
this.obsevers = [...obrs];
}
// 添加观察者关注这个对象
Sub.prototype.add = function(obr) {
this.obsevers.push(obr)
}
// 被关注的对象,如果更新了就可以调用这个通知方法,去通知所有的观察者去更新
Sub.prototype.notify = function() {
for(let obr of this.obsevers) {
if(typeof obr.update === 'function') {
obr.update();
}
}
}
// 例如:
let obj1 = {
update: () => {
console.log("update obj1");
}
}
let obj2 = {
update: () => {
console.log("update obj2");
}
}
// 添加观察者
let sub = new Sub(obj1, obj2);
/** 假设这里有一些操作,使得sub更新了,然后通知所有的观察者去执行它们自己的更新操作 */
// 通知观察者
sub.notify();
发布订阅模式
发布者状态更新时,发布某些类型的通知,而中间控制器只通知订阅了相关类型的订阅者。发布者和订阅者之间是没有直接关联的。消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。它们都依托于中间的事件总线。
代码样例:
const EventListener = function() {
this.map = new Map();
}
/**
* 订阅消息
* @param {any} e 订阅的消息类型
* @param {function} fn 订阅后,如果有消息时,需要触发的方法
*/
EventListener.prototype.on = function(e, fn) {
// 判断是否已经有了订阅的消息类型,有的话就把订阅的方法传入,否则就新建类型
let eventList = this.map.get(e);
if(!eventList) {
this.map.set(e, [fn])
} else {
eventList.push(fn);
}
}
/**
* 发布消息
* @param {any} e 订阅的消息类型
* @param {...any} arg 发布出去的消息
*/
EventListener.prototype.emit = function(e, ...arg) {
// 找到发布的消息类型,然后发布消息
let eventList = this.map.get(e);
if(eventList) {
for(let fn of eventList) {
fn(...arg);
}
} else {
return false;
}
}
// 例如
let eventListener = new EventListener();
let user1 = {
// user1 更新消息后的回调
update: (...msg) => {
console.log("课程更新记录:", ...msg);
}
}
let user2 = {
// user2 更新消息后的回调
update: (...msg) => {
console.log("游戏更新记录:", ...msg);
}
}
// 分别订阅不同的类型的事件
eventListener.on("class", user1.update)
eventListener.on("game", user2.update)
// 推送不同类型事件的更新消息
eventListener.emit("class", "计算机网络", "毛概")
eventListener.emit("game", "原神")
网友评论