java观察者订阅模式_观察者模式和发布订阅模式的区别

之前一直对观察者模式和发布订阅模式的区别理解不深,正好这段时间在看vue源码的分析,vue数据双向绑定也用到了发布订阅模式,于是又把这两者探究了一番,今天做个笔记加强印象。

观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。

24419e1a1d60d258fe110f757f7fb788.png

pubSub.png

从图中可以看出,观察者模式中观察者和目标直接进行交互,而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。

接下来看一下代码实现

观察者模式:

// 观察者

class Observer {

constructor() {

}

update(val) {

}

}

// 观察者列表

class ObserverList {

constructor() {

this.observerList = []

}

add(observer) {

return this.observerList.push(observer);

}

remove(observer) {

this.observerList = this.observerList.filter(ob => ob !== observer);

}

count() {

return this.observerList.length;

}

get(index) {

return this.observerList(index);

}

}

// 目标

class Subject {

constructor() {

this.observers = new ObserverList();

}

addObserver(observer) {

this.observers.add(observer);

}

removeObserver(observer) {

this.observers.remove(observer);

}

notify(...args) {

let obCount = this.observers.count();

for (let index = 0; index < obCount; index++) {

this.observers.get(i).update(...args);

}

}

}

发布订阅模式:

class PubSub {

constructor() {

this.subscribers = {}

}

subscribe(type, fn) {

if (Object.prototype.hasOwnProperty.call(this.subscribers, type)) {

this.subscribers[type] = [];

}

this.subscribers[type].push(fn);

}

unsubscribe(type, fn) {

let listeners = this.subscribers[type];

if (!listeners || !listeners.length) return;

this.subscribers[type] = listeners.filter(v => v !== fn);

}

publish(type, ...args) {

let listeners = this.subscribers[type];

if (!listeners || !listeners.length) return;

listeners.forEach(fn => fn(...args));

}

}

let ob = new PubSub();

ob.subscribe('add', (val) => console.log(val));

ob.publish('add', 1);

从上面代码可以看出,观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,会造成代码的冗余。而发布订阅模式则统一由调度中心处理,消除了发布者和订阅者之间的依赖。

观察者模式跟我们平时用的事件也有一定的关系,比如:

ele.addEventListener('click', () => {});

addEventListener就相当于注册了一个观察者,当观察到‘click’事件的时候,作出一些处理。

好啦,内容基本就这些,如果有什么不对的地方,欢迎指正哦~

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页