如何实现观察者模式和发布-订阅模式?

要实现观察者模式和发布-订阅模式,你需要遵循一些基本的步骤和原则。下面分别介绍这两种模式的实现方法。

如何实现观察者模式:

观察者模式(Observer Pattern)是一种行为设计模式,用于维护观察者(Observer)对象与被观察者(Subject)对象之间的关系。这种关系是一对多的关系,即一个被观察者可以有多个观察者,当被观察者发生变化时,所有注册的观察者都会收到通知并进行相应的更新。

  1. 定义一个Subject(被观察者)类,包含以下内容:
  • 一个保存Observer(观察者)对象的列表。
  • 注册Observer的方法(addObserver)。
  • 移除Observer的方法(removeObserver)。
  • 通知所有Observer的方法(notifyObservers)。
  1. 定义一个Observer接口,包含以下内容:
  • 更新的方法(update)。
  1. 实现Observer接口的ConcreteObserver类(具体的观察者)。
  2. 使用Subject类和Observer接口来建立系统中的观察者和被观察者之间的关系。

如何实现发布-订阅模式:

发布-订阅模式(Publish-Subscribe Pattern)也是一种消息传递模式,与观察者模式类似,但它通常涉及一个称为Broker的中间实体,以维持发布者(Publisher)和订阅者(Subscriber)之间的解耦状态。

  1. 定义一个Publisher(发布者)类,包含以下内容:
  • 发布消息的方法(publish)。
  1. 定义一个Subscriber(订阅者)类,包含以下内容:
  • 订阅消息的方法(subscribe)。
  • 取消订阅的方法(unsubscribe)。
  1. 定义一个Broker(经纪人)类,包含以下内容:
  • 保存Publisher和Subscriber对象的列表。
  • 注册Publisher和Subscriber的方法。
  • 当Publisher发布消息时,通过Broker将消息分发给感兴趣的Subscriber。
  1. 使用Publisher类、Subscriber类和Broker类来建立系统中的发布者、订阅者和经纪人之间的关系。

代码示例:

以下是两种模式的一个简化版的JavaScript实现:

观察者模式

js 复制代码
class Observer {
  update() {
    console.log('Observer has been updated.');
  }
}
 
class Subject {
  constructor() {
    this.observers = [];
  }
 
  addObserver(observer) {
    this.observers.push(observer);
  }
 
  removeObserver(observer) {
    const index = this.observers.indexOf(observer);
    if (index > -1) {
      this.observers.splice(index, 1);
    }
  }
 
  notifyObservers() {
    this.observers.forEach(observer => observer.update());
  }
}
 
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
 
subject.addObserver(observer1);
subject.addObserver(observer2);
 
subject.notifyObservers(); // Observer has been updated.

发布-订阅模式

js 复制代码
class Publisher {
  publish(message) {
    console.log(`Publisher: ${message}`);
  }
}
 
class Subscriber {
  subscribe(message) {
    console.log(`Subscriber: ${message}`);
  }
}
 
class Broker {
  constructor() {
    this.publishers = [];
    this.subscribers = [];
  }
 
  register(publisher) {
    this.publishers.push(publisher);
  }
 
  register(subscriber) {
    this.subscribers.push(subscriber);
  }
 
  distribute(message) {
    this.subscribers.forEach(subscriber => subscriber.subscribe(message));
  }
}
 
const broker = new Broker();
const publisher = new Publisher();
const subscriber1 = new Subscriber();
const subscriber2 = new Subscriber();
 
broker.register(publisher);
broker.register(subscriber1);
broker.register(subscriber2);
 
publisher.publish('Hello'); // Subscriber: Hello

请注意,实际应用中可能需要更复杂的逻辑和错误处理,但这些示例足以展示两种模式的基本概念。

相关推荐
M ? A13 分钟前
Vue转React最佳工具对比:Vuera、Veaury与VuReact
前端·javascript·vue.js·经验分享·react.js
We་ct19 分钟前
JS手撕:函数进阶 & 设计模式解析
开发语言·前端·javascript·设计模式·面试·前端框架
悟空瞎说34 分钟前
前端老鸟实战:纯 CSS 实现小红书「真・瀑布流」,零 JS、自动错落、生产可用
前端
yuki_uix34 分钟前
当 reduce 遇到二维数据:从"聚合直觉"到"复合 Map"的思维跃迁
前端·javascript·面试
我叫黑大帅38 分钟前
Vue3中的computed 与 watch 的区别
前端·javascript·面试
暗不需求40 分钟前
# 一文搞懂 JavaScript 内存机制:从栈和堆,到闭包为什么“活得更久”
前端·javascript
CharlesY40 分钟前
JavaScript HTML5 Cache Manifest:离线应用缓存机制考古
前端·javascript
yuki_uix40 分钟前
前端解题的 6 个思维模型:比记答案更有用的东西
前端·面试
Bigger1 小时前
第三章:我是如何剖析 Claude Code 工具系统与命令执行机制的
前端·claude·源码阅读
GISer_Jing1 小时前
告别手搓架构图!Excalidraw+AI Skills 高效绘制手绘风技术图
前端·人工智能·react.js