原文合集地址如下,有需要的朋友可以关注
什么是发布者/订阅者模式
发布者-订阅者模式是一种软件设计模式,用于实现对象之间的一对多依赖关系。在这种模式中,一个对象(被称为发布者)而其他对象(成为订阅者)可以在发布者上注册自己,以接受特定事件或消息的通知。
发布者: 负责维护订阅者列表和发布事件或消息。当某个事件或消息发生时,发布者将通知发送给所有订阅者。
订阅者:注册在发布者上,以接受感兴趣的事件或消息的通知。当发布者发布相应事件时,订阅者相应做出响应。
工作流程:
- 发布者维护一个订阅者列表,并提供注册、注销和通知的方法。
- 订阅者注册自己到发布者上,表明自己对某个事件或消息感兴趣。
- 当发布者发布相应的事件或消息时,会遍历订阅者列表,将通知发送给所有订阅者。
- 订阅者收到通知后,执行相应的处理逻辑。
优点:
- 实现了松耦合:发布者和订阅者之间相互独立,可以方便的删除和增加订阅者,而不影响其他代码部分。
- 提高代码复用性:多个订阅者可以共享同一个发布者,
在这里插入代码片
从而实现代码的复用。
应用场景: - GUI应用程序中的事件处理机制。
- 前端框架中的监听和消息通知。
- JS中的自定义事件。
结合例子理解:
// 发布者 (Publisher/Subject)
class Publisher {
constructor() {
this.subscribers = [];
}
// 注册订阅者
subscribe(subscriber) {
this.subscribers.push(subscriber);
}
// 取消订阅
unsubscribe(subscriber) {
this.subscribers = this.subscribers.filter((sub) => sub !== subscriber);
}
// 发布事件通知
publish(message) {
this.subscribers.forEach((subscriber) => subscriber.receive(message));
}
}
// 订阅者 (Subscriber/Observer)
class Subscriber {
constructor(name) {
this.name = name;
}
// 接收事件通知
receive(message) {
console.log(`${this.name} received: ${message}`);
}
}
// 创建发布者实例
const publisher = new Publisher();
// 创建订阅者实例
const subscriberA = new Subscriber('Subscriber A');
const subscriberB = new Subscriber('Subscriber B');
// 订阅者注册到发布者上
publisher.subscribe(subscriberA);
publisher.subscribe(subscriberB);
// 发布者发布事件通知
publisher.publish('Hello World!');
// 取消订阅者A的订阅
publisher.unsubscribe(subscriberA);
// 再次发布事件通知
publisher.publish('How are you?');
在这个例子中,创建了一个简单的发布者类Publisher和一个订阅者类Subscriber。发布者维护一个订阅者列表,并提供subscribe方法用于注册订阅者,unsubscribe用于取消订阅,publish方法用于发布事件通知。
输出结果:
Subscriber A received: Hello World!
Subscriber B received: Hello World!
Subscriber B received: How are you?
在输出结果中,可以看到订阅者A和订阅者B都收到了 "Hello World!" 的事件通知。然后取消了订阅者A的订阅,再次发布事件通知时,
只有订阅者B收到了 "How are you?" 的事件通知。这展示了发布者-订阅者模式的工作机制:多个订阅者可以订阅同一个发布者,
发布者发布事件通知时,所有订阅者都会收到相应的通知。同时,订阅者可以根据自己的需求注册和取消订阅,从而实现灵活的事件处理。
观察者模式
实际上,发布者-订阅者模式和观察者模式是同一种模式,只是在不同的文献或资料中可能称呼不同。
在发布者-订阅者模式中,有一个调用中心(或者称为发布者或主题),它负责维护订阅者列表和发布事件或消息。
其他对象(订阅者或观察者)可以注册自己到调用中心,以接收特定事件或消息的通知。
需要注意的是,虽然两种模式的概念相似,但在具体实现上可能有一些差异。
不同的开发框架或库可能有不同的实现方式,但总体的思想和目标都是相同的。选择使用哪种模式取决于具体的应用场景和需求。
用观察者模式举个例子:
// 被观察者 (Subject)
class Subject {
constructor() {
this.observers = [];
}
// 注册观察者
addObserver(observer) {
this.observers.push(observer);
}
// 注销观察者
removeObserver(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
}
// 发送通知给所有观察者
notify(message) {
this.observers.forEach((observer) => observer.update(message));
}
}
// 观察者 (Observer)
class Observer {
constructor(name) {
this.name = name;
}
// 接收通知
update(message) {
console.log(`${this.name} received: ${message}`);
}
}
// 创建被观察者实例
const subject = new Subject();
// 创建观察者实例
const observerA = new Observer('Observer A');
const observerB = new Observer('Observer B');
// 观察者注册到被观察者上
subject.addObserver(observerA);
subject.addObserver(observerB);
// 被观察者发送通知
subject.notify('Hello World!');
// 观察者注销
subject.removeObserver(observerA);
// 再次发送通知
subject.notify('How are you?');
输出结果与之前的发布者-订阅者模式相同:
Observer A received: Hello World!
Observer B received: Hello World!
Observer B received: How are you?
总结
在实际开发中,无论是使用观察者模式还是订阅者-发布者模式,它们的基本思想和用法是相同的:一个对象(被观察者或发布者)维护一个观察者列表,其他对象(观察者或订阅者)可以注册自己到这个列表中,以接收特定事件或消息的通知。当事件或消息发生时,被观察者或发布者会遍历观察者列表,将通知发送给所有观察者或订阅者。