废话少说,直接上图
观察者模式(Observer pattern)
顾名思义,观察者模式,就会存在 “被观察者” and “观察者”,两者直接“面对面交流”,不存在任何中间人,为 “松耦合”。
看图: 干饭人在看, 主厨在做,随时准备恰饭
主厨饭菜做好了 (状态发生改变),开始呼叫干饭人,干凡人收到主厨的通知,飞奔过去干饭 (开始工作)
总结:
订阅发布模式(Publish–subscribe pattern)
订阅发布模式,与 “观察者模式” 不同的是,“订阅者” 与 “发布者” 之间几乎没有见过面,也不认识对方,一切的交流都交由第三方,也就是 “中间人” 完成,属于完全解耦
看图:
看上图可以知道,所有通讯均由 “第三者完成”, 发布者,订阅者,在第三者的任务平台各取所需。而且,无论提前订阅,或者之后订阅,只要发布者任务信息更新,就会通知订阅者。
看图还不明白?看这里给你说道说道
观察者 and 订阅发布 区别
观察者: (观察 | 被观察者)
“观察者”直接观察被“被观察者”,当“被观察者”状态发生改变,
则做出对应反应
订阅发布: (发布者 | 事件调度中心 | 订阅者)
所有事件统一由事件调度中心管理,
“发布者”可以在事件中发布事件,
“订阅者”自主选择订阅消息,
“事件调度中心”接受到对应信息发布,则会通知“订阅者”,途中“事件调度中心”可以做任何处理。
区别:
发布观察者模式中,“观察者”and”被观察者“存在松耦合.
订阅者模式中: 所有处理交由第三者“事件调度中心”(中介),“发布者”and“订阅者”完全解耦
程序实践才是王道,上代码!!!
** 观察者模式**
// 观察者
class Observer {
constructor(name) {
this.name = name;
}
// 发现更新
update() {
console.log(this.name, ': 我观察的东西更新了。')
// 执行工作
this.woke();
}
woke() {
console.log(this.name, ': 开始工作');
}
}
// 观察者列表 - 实际作用,封装观察者增删改查
class ObserverList {
constructor(arg) {
this.observerList = [];
}
addObserver(observer) {
this.observerList.push(observer)
}
remove(observer) {
this.observerList = this.observerList.filter(item => observer !== item);
}
count() {
return this.observerList.length;
}
get(i) {
return this.observerList[i];
}
}
// 目标
class Subscribe {
constructor(arg) {
this.observers = new ObserverList();
}
// 增加观察者
addObserver(observer) {
this.observers.addObserver(observer);
}
// 状态变更通知
notice() {
console.log('被人更新了');
let len = this.observers.count();
for (let i = 0; i < len; i++) {
this.observers.get(i).update();
}
}
}
复制代码
订阅发布模式
// 订阅发布模式
class EventList {
constructor() {
this.events = {};
}
subscribe(key, fn) {
if (!Object.prototype.hasOwnProperty.call(this.events, key)) {
this.events[key] = [];
}
this.events[key].push(fn);
}
unSubscribe(key, fn) {
let eventList = this.events[key];
if (!eventList || eventList.length == 0) return;
this.events[key] = this.events[key].filter(f => f !== fn);
}
publish(key, ...args) {
let eventList = this.events[key];
console.log(key, eventList);
if (!eventList || eventList.length == 0) return;
eventList.forEach(f => f(...args))
}
}
let ev = new EventList();
let op = ['123'];
ev.subscribe(op, (...args) => {
console.log('t事件执行了', args);
})
ev.subscribe(op, args => {
console.log('t2事件执行了', args);
})
ev.publish(op, 123, 5555)
// -> 't事件执行了' [123, 555]
// -> 't2事件执行了' 123
复制代码
总结
观察者模式 - 主要是 观察者 和 被观察者 的逻辑实现
订阅发布模式 - 主要是 事件调度中心 的逻辑实现