前端中的观察者模式和发布订阅模式
2023-03-23 本文已影响0人
西叶web
观察者模式和发布订阅模式都是前端开发中常用的设计模式,虽然它们的目的相似(实现解耦合),但是它们具体的实现方式和应用场景有所不同。
观察者模式:
观察者模式有一个或多个观察者对象(订阅者),一个主题对象(被观察者)。当主题对象的状态发生变化时,会通知所有的观察者,使其能自动更新其本身。这是一种1:n的关系,一个主题对象可以通知多个观察者。
下面是一个简单的示例:
// 主题对象
class Subject {
constructor() {
this.observers = [];
}
add(observer) {
this.observers.push(observer);
}
remove(observer) {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
notify() {
this.observers.forEach(observer => observer.update());
}
}
// 观察者对象
class Observer {
constructor(name, subject) {
this.name = name;
this.subject = subject;
this.subject.add(this);
}
update() {
console.log(`${this.name} notified`);
}
}
// 测试
const subject = new Subject();
const observerA = new Observer('A', subject);
const observerB = new Observer('B', subject);
subject.notify();
subject.remove(observerB);
subject.notify();
发布订阅模式:
发布订阅模式也有一个或多个订阅者和一个发布者,不同的是,在发布订阅模式中,并非将发布者直接通知所有的订阅者,而是通过一个消息代理(即Pub/Sub)来完成。发布者将消息发布到消息代理中,消息代理再将消息分发给所有的订阅者。这是一种1:n的关系,一个消息可以被多个订阅者接收。
下面是一个简单的示例:
// 消息代理
class PubSub {
constructor() {
this.subscribers = {};
}
subscribe(callback, topic = 'default') {
if (!this.subscribers[topic]) {
this.subscribers[topic] = [];
}
this.subscribers[topic].push(callback);
}
publish(data, topic = 'default') {
if (this.subscribers[topic]) {
this.subscribers[topic].forEach(subscriber => subscriber(data, topic));
}
}
}
// 测试
const pubSub = new PubSub();
const subscriberA = (data, topic) => console.log(`A receive message from ${topic}: ${data}`);
const subscriberB = (data, topic) => console.log(`B receive message from ${topic}: ${data}`);
pubSub.subscribe(subscriberA);
pubSub.subscribe(subscriberB, 'topicA');
pubSub.publish('Hello World');
pubSub.publish('Hello TopicA', 'topicA');
不同点:
在观察者模式中,主题对象和观察者对象是直接耦合的;而在发布订阅模式中,发布者和订阅者之间是通过一个消息代理来解耦的。
在观察者模式中,主题对象的状态变化只能通知观察者,观察者不能感知其他观察者的存在;而在发布订阅模式中,有多个订阅者,它们可以独立地订阅和接收特定主题的消息,也可以取消订阅。
观察者模式适用于1:n的关系;
发布订阅模式适用于1:n/n:1/n:n的关系。
以上是两种模式的区别和示例,需要根据实际的场景选择适合的模式来实现解耦。