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

 

发布订阅模式(Publish-Subscribe)与观察者模式(Observer Pattern)

发布订阅模式和观察者模式都属于常见的设计模式,用于在一个对象的状态变化时,通知其他对象。然而,它们的实现方式和适用场景略有不同。接下来,我们分别解释这两种模式的差异,并提供 JavaScript 示例代码来说明。


观察者模式(Observer Pattern)

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系。当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。观察者模式通常有一个主题(Subject)和多个观察者(Observer),主题直接通知观察者。

  • 特点:主题和观察者直接耦合。
  • 适用场景:当一个对象的变化需要影响到多个对象,并且这些对象之间的关系是直接的、紧密的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 主题(Subject)
class Subject {
  constructor() {
    this.observers = [];
  }
 
  // 添加观察者
  addObserver(observer) {
    this.observers.push(observer);
  }
 
  // 移除观察者
  removeObserver(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }
 
  // 通知所有观察者
  notifyObservers(message) {
    this.observers.forEach(observer => observer.update(message));
  }
}
 
// 观察者(Observer)
class Observer {
  constructor(name) {
    this.name = name;
  }
 
  // 更新方法
  update(message) {
    console.log(`${this.name} received message: ${message}`);
  }
}
 
// 使用示例
const subject = new Subject();
 
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");
 
subject.addObserver(observer1);
subject.addObserver(observer2);
 
subject.notifyObservers("New update available!");
 
// Output:
// Observer 1 received message: New update available!
// Observer 2 received message: New update available!

  

发布订阅模式(Publish-Subscribe Pattern)

发布订阅模式与观察者模式非常相似,但存在一些重要区别。在发布订阅模式中,消息的发布者(Publisher)并不知道订阅者(Subscriber)的存在。发布者和订阅者之间没有直接的依赖关系。相反,通过一个中介(Broker)(通常是一个事件总线),发布者发布消息,订阅者可以根据需要选择接收这些消息。

  • 特点:发布者和订阅者解耦,通过中介进行消息传递。
  • 适用场景:当发布者和订阅者之间的关系较松散,并且消息的传递是异步的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 事件总线(Broker)
class EventBus {
  constructor() {
    this.subscribers = {};
  }
 
  // 订阅事件
  subscribe(event, callback) {
    if (!this.subscribers[event]) {
      this.subscribers[event] = [];
    }
    this.subscribers[event].push(callback);
  }
 
  // 发布事件
  publish(event, message) {
    if (this.subscribers[event]) {
      this.subscribers[event].forEach(callback => callback(message));
    }
  }
 
  // 取消订阅事件
  unsubscribe(event, callback) {
    if (this.subscribers[event]) {
      this.subscribers[event] = this.subscribers[event].filter(cb => cb !== callback);
    }
  }
}
 
// 使用示例
const eventBus = new EventBus();
 
const subscriber1 = (message) => console.log(`Subscriber 1 received: ${message}`);
const subscriber2 = (message) => console.log(`Subscriber 2 received: ${message}`);
 
eventBus.subscribe("news", subscriber1);
eventBus.subscribe("news", subscriber2);
 
eventBus.publish("news", "Breaking news: JavaScript is awesome!");
 
// Output:
// Subscriber 1 received: Breaking news: JavaScript is awesome!
// Subscriber 2 received: Breaking news: JavaScript is awesome!

  

主要区别如下:

 

posted @   我是格鲁特  阅读(130)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-12-04 less或scss中波浪符的使用场景
点击右上角即可分享
微信分享提示