前言
hello,大家好!我是图图酱,今天就和大家分享一下设计模式里的观察者模式
和发布订阅模式
,很多人对于这两种设计模式的概念可能有点模糊分不清,有的觉得这两种模式其实是一样的。其实这两种确实很类似但是略有区别,下面就通过简单的实现带大家弄懂这两种模式的区别及用法。
观察者&发布订阅
首先通过上图我们可以清楚的看到两者的区别。
- 观察者模式是通过观察者(
Observer
)直接对目标(Subject
)进行订阅(Subscribe
),事件通知也是由目标直接通知观察者,两者直接是直接关联的。 - 发布订阅模式在观察者模式之前多了一个时间时间调度中心(
Event Channel
),订阅者(Subscriber
)和发布者(Publisher
)不是直接关联的,两者直接的消息传递需要经过调度中心来进行,这样的好处就是做到了松散解耦,更为灵活。
Linus Torvalds --- 'Talk is cheap . Show me the code.'
观察者模式
js
// 定义一个目标对象
class Subject {
constructor() {
this.Observers = [];
}
add(observer) {
//添加
this.Observers.push(observer);
}
remove(observer) {
//移除
this.Observers.filter((item) => item === observer);
}
notify() {
//通知所有观察者
this.Observers.forEach((item) => {
item.update();
});
}
}
//定义观察者对象
class Observer {
constructor(name) {
this.name = name;
}
update() {
console.log(`my name is:${this.name}`);
}
}
// 实例化目标对象
let sub = new Subject();
let obs1 = new Observer("observer11");
let obs2 = new Observer("observer22");
sub.add(obs1);
sub.add(obs2);
sub.notify();
观察者模式由目标(Subject)维护对应的观察者对象(Observer),在需要通知时再由目标去通知其维护的观察者对象,主要的调度工作都在观察者这里
发布订阅模式
js
// 事件中心
class Events {
// 订阅者列表
events = {};
// 订阅
subscribe(key, fn) {
if (!Array.isArray(this.subscriber[key])) {
this.subscriber[key] = [];
}
this.subscriber[key].push(fn);
}
// 取消单个订阅
unsubscribe(key, fn) {
const subscribers = this.subscriber[key] || [];
this.subscriber[key] = subscribers.filter((_fn) => _fn !== fn);
}
// 取消所有订阅
unsubscribeAll(key) {
this.subscriber[key] = [];
}
// 发布
publish(key, ...args) {
const subscribers = this.subscriber[key] || [];
if (subscribers.length === 0) {
console.log("has't subscriber");
}
subscribers.forEach((subscriber) => {
subscriber.apply(this, args);
});
}
}
// 创建发布订阅信道中介
const e = new Events();
// 发布者
const publisher = {
article1: 'article1',
article2: 'article2',
};
// 订阅者
const subscriber1 = (article) => {
console.log(`sub1 receive ${article}`);
};
const subscriber2 = (article) => {
console.log(`sub2 receive ${article}`);
};
// 订阅操作
e.subscribe('event1', subscriber1);
e.subscribe('event1', subscriber2);
// 发布操作
e.publish('event1', publisher.article1);
// sub1 receive article1
// sub2 receive article1
// 多事件发布订阅
e.subscribe('event2', subscriber1);
e.publish('event2', publisher.article1);
// sub1 receive article1
// 取消单个订阅
e.unsubscribe('event1', subscriber1);
e.publish('event1', publisher.article2);
// sub2 receive article2
// 取消所有订阅
e.unsubscribeAll('event1');
e.publish('event1');
// has't subscriber
发布订阅模式有一个单独的调度中心(
Events
),它在这里负责了在观察者模式里由观察者(Observer
)维护的调度工作,这样订阅者(Subscriber
)发布者(Publisher
)就变得纯粹,发布者只需要发布事件,订阅者做好接到响应需要的回调。
小结
- 可以理解为观察者模式里,目标(
Subject
)维护了一个观察者(Observer
)列表,[obs1, obs2],在发布时通知这个观察者列表里的观察者,发布订阅里,事件中心(Events)维护的是个{event1: [sub1, sub2], event2: [sub1, sub3]}事件对象 - 观察者模式由具体目标(
Subject
)调度,发布订阅模式由调度中心(Events
)统一调度,发布订阅模式比观察者模式多一个调度中心 - 在发布订阅模式中,组件是松散耦合的,观察者模式相反。
ok👌,到这里,大家是不是对于这两种设计模式有了清晰的了解了呢😉,以上是个人对于这两个设计模式的理解,如有错误请多指教🫡