观察者模式与发布-订阅模式的对决

在这里插入图片描述

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》《带你从入门到实战全面掌握 uni-app》

摘要:

本文将深入探讨观察者模式和发布-订阅模式,分析它们的异同、应用场景以及优缺点。通过了解这两种模式,我们可以更好地应对不同的开发需求,选择合适的模式来实现代码的解耦和模块化。

引言:

在软件工程中,为了实现代码的解耦和模块化,我们常常会用到一些设计模式。观察者模式和发布-订阅模式是最常用的两种模式,它们在某些方面有着相似之处,但在实际应用中又存在差异。本文将详细介绍这两种模式,帮助大家在实际开发中做出合适的选择。

正文:

1️⃣ 观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

  • 优点:实现了对象之间的解耦,提高代码的可维护性和可扩展性。
  • 缺点:观察者和被观察者之间的高度耦合,可能导致代码的复杂性增加。

观察者模式是一种设计模式,允许一个对象(称为“主题”)注册一个或多个其他对象(称为“观察者”)以便在某个事件发生时被通知。

以下是一个简单的JavaScript观察者模式代码示例:

// 主题构造函数
function Subject() {
  this.observers = []; // 数组用于存放观察者对象
}

// 注册观察者
Subject.prototype.subscribe = function(observer) {
  this.observers.push(observer);
};

// 移除观察者
Subject.prototype.unsubscribe = function(observer) {
  const index = this.observers.indexOf(observer);
  if (index > -1) {
    this.observers.splice(index, 1);
  }
};

// 通知所有观察者
Subject.prototype.notify = function(data) {
  this.observers.forEach(observer => observer.update(data));
};

// 观察者构造函数
function Observer(name) {
  this.name = name;
}

// 观察者更新方法
Observer.prototype.update = function(data) {
  console.log(`${this.name} received notification:`, data);
};

// 创建主题实例
const subject = new Subject();

// 创建观察者实例
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");

// 注册观察者
subject.subscribe(observer1);
subject.subscribe(observer2);

// 通知观察者
subject.notify("Hello, observers!");

在这个示例中,我们创建了一个主题(Subject)构造函数和一个观察者(Observer)构造函数。主题具有订阅(subscribe)、移除(unsubscribe)和通知(notify)观察者的方法。观察者具有更新(update)方法。

然后我们创建了主题和观察者的实例,并注册观察者到主题。最后,我们通过调用主题的notify方法来通知观察者。

2️⃣ 发布-订阅模式

发布-订阅模式是一种消息传递模式,它允许发布者发送消息到消息队列,而订阅者可以订阅感兴趣的消息并接收通知。

  • 优点:实现了发布者和订阅者之间的完全解耦,提高了代码的模块化和灵活性。
  • 缺点:可能导致系统的性能开销增加,因为需要维护一个消息队列。

发布-订阅模式是一种设计模式,允许一个对象(发布者)发布消息,其他多个对象(订阅者)监听并接收这个消息。

以下是一个简单的JavaScript发布-订阅模式代码示例:

// 发布者构造函数
function Publisher() {
  this.subscribers = {}; // 对象用于存放订阅者及其回调函数
}

// 发布消息
Publisher.prototype.publish = function(topic, data) {
  if (this.subscribers[topic]) {
    this.subscribers[topic].forEach(subscriber => subscriber(data));
  }
};

// 订阅者构造函数
function Subscriber(name) {
  this.name = name;
}

// 订阅消息
Subscriber.prototype.subscribe = function(topic, callback) {
  if (!this.publisher.subscribers[topic]) {
    this.publisher.subscribers[topic] = [];
  }
  this.publisher.subscribers[topic].push(callback);
};

// 创建发布者和订阅者实例
const publisher = new Publisher();
const subscriber1 = new Subscriber("Subscriber 1");
const subscriber2 = new Subscriber("Subscriber 2");

// 订阅消息
subscriber1.subscribe("topic1", data => {
  console.log(`${subscriber1.name} received message:`, data);
});

subscriber2.subscribe("topic1", data => {
  console.log(`${subscriber2.name} received message:`, data);
});

// 发布消息
publisher.publish("topic1", "Hello, subscribers!");

在这个示例中,我们创建了一个发布者(Publisher)构造函数和一个订阅者(Subscriber)构造函数。发布者具有发布(publish)消息的方法,订阅者具有订阅(subscribe)消息的方法。

然后我们创建了发布者和订阅者的实例,并让订阅者订阅发布者的消息。最后,我们通过调用发布者的publish方法来发布消息,订阅者将接收到这个消息。

3️⃣ 观察者模式与发布-订阅模式的异同

虽然观察者模式和发布-订阅模式在功能上有些相似,但它们在实际应用中存在一些差异:

  • 耦合度:观察者模式中的观察者和被观察者是直接关联的,而发布-订阅模式中的发布者和订阅者是通过消息队列进行通信的,实现了更低的耦合度。
  • 灵活性:发布-订阅模式更加灵活,因为它允许订阅者动态地订阅和取消订阅消息。
    总结:观察者模式和发布-订阅模式都是实现代码解耦和模块化的有效手段。在实际开发中,我们需要根据项目需求和场景来选择合适的模式。观察者模式适用于对象间高度耦合的场景,而发布-订阅模式适用于需要高度解耦和模块化的场景。

参考资料:

  • “设计模式:观察者模式和发布-订阅模式”,极客时间,2022
  • “深入理解观察者模式和发布-订阅模式”,掘金,2021

相关推荐

  1. 发布订阅模式观察模式详解

    2024-04-10 11:36:02       36 阅读
  2. 观察模式发布-订阅模式有什么异同

    2024-04-10 11:36:02       21 阅读
  3. 如何实现观察模式发布-订阅模式

    2024-04-10 11:36:02       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-10 11:36:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-10 11:36:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-10 11:36:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-10 11:36:02       20 阅读

热门阅读

  1. 【linux】cp命令介绍以及使用范例

    2024-04-10 11:36:02       13 阅读
  2. python——运算符

    2024-04-10 11:36:02       10 阅读
  3. 开发环境解决跨域问题

    2024-04-10 11:36:02       12 阅读
  4. MyBatis如何实现分页

    2024-04-10 11:36:02       13 阅读
  5. Http Download

    2024-04-10 11:36:02       12 阅读
  6. 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(3)

    2024-04-10 11:36:02       13 阅读
  7. conda activate xxx-env出现错误CommandNotFoundError

    2024-04-10 11:36:02       10 阅读