观察者设计模式在Js中的使用

观察者设计模式

定义

一种行为型设计模式,用于在对象之间建立一种一对多的依赖关系 ,当一个对象的状态发生变化 时,它的所有依赖对象 都会收到通知并自动更新。

参与者

1. \color{red}{1.} 1. 主题 (Subject):也称为被观察者或可观察对象 ,它维护 着一组观察者对象,并提供了添加、删除和通知观察者的方法。主题可以是具体的类或接口。

2. \color{red}{2.} 2. 观察者 (Observer):也称为订阅者,它定义了接收和处理主题通知的方法 。观察者通过注册到主题上来接收通知,并根据通知进行相应的操作。观察者可以是具体的类或接口。

在观察者设计模式中,主题和观察者之间是松耦合的关系。主题并不直接调用观察者的方法,而是通过通知的方式告知观察者发生了变化。观察者通过注册到主题上来表明自己感兴趣的事件,并在事件发生时接收到通知。

核心思想

解耦发布者 和订阅者 ,使得两者之间能够独立变化 。当一个对象的状态发生变化时,所有依赖于它的观察者都会得到通知,并自动更新以反映最新的状态。

应用场景

  • GUI 事件处理 :图形用户界面(GUI)中的按钮、菜单项和其他控件通常作为主题,可以被不同的观察者订阅,以响应用户的交互操作。
  • 消息队列系统 :在消息队列系统中,生产者 发送消息到主题,而消费者作为观察者订阅主题来接收和处理消息。
  • 数据库通知机制 :数据库中的触发器 和事件通知机制 可以使用观察者模式来实现。触发器可以充当主题,而订阅该触发器的存储过程或应用程序可以作为观察者进行相应的处理。
  • 股票市场更新 :股票市场中的投资者 可以作为观察者订阅特定股票的主题,以接收价格更新的通知。

示例

typescript 复制代码
// 主题接口
interface Subject {
  registerObserver(observer: Observer): void;
  removeObserver(observer: Observer): void;
  notifyObservers(): void;
}

// 观察者接口
interface Observer {
  update(data: any): void;
}

// 具体主题类
class ConcreteSubject implements Subject {
  private observers: Observer[] = [];
  private data: any;

  registerObserver(observer: Observer): void {
    this.observers.push(observer);
  }

  removeObserver(observer: Observer): void {
    const index = this.observers.indexOf(observer);
    if (index !== -1) {
      this.observers.splice(index, 1);
    }
  }

  notifyObservers(): void {
    for (const observer of this.observers) {
      observer.update(this.data);
    }
  }

  setData(data: any): void {
    this.data = data;
    this.notifyObservers();
  }
}

// 具体观察者类
class ConcreteObserver implements Observer {
  private name: string;

  constructor(name: string) {
    this.name = name;
  }

  update(data: any): void {
    console.log(`Observer ${this.name} received data: ${data}`);
  }
}

// 客户端代码
const subject = new ConcreteSubject();

const observer1 = new ConcreteObserver("Observer 1");
const observer2 = new ConcreteObserver("Observer 2");

subject.registerObserver(observer1);
subject.registerObserver(observer2);

subject.setData("Hello world!");

前端应用

1. \color{red}{1.} 1. 事件处理 :在 JavaScript 和浏览器中,事件机制就是观察者设计模式的实现 。DOM 元素 可以作为主题 ,而事件监听函数 则充当观察者。当事件发生时,主题会通知所有注册的观察者执行相应的事件处理函数。

2. \color{red}{2.} 2. AJAX 请求 :在使用 XMLHttpRequest 或 Fetch API 发起 AJAX 请求时,我们可以将请求对象 作为主题 ,而回调函数 作为观察者。当请求返回结果时,主题会通知观察者进行相应的处理。

3. \color{red}{3.} 3. 订阅-发布(Pub/Sub)模式:该模式是观察者模式的一种变体,在 JavaScript 中被广泛应用于消息传递和事件系统。通过订阅和发布机制,多个订阅者可以同时订阅特定的主题,并在主题发生变化时接收通知。

4. \color{red}{4.} 4. 数据绑定和响应式框架 :许多前端框架和库,如 Vue.js 和 React.js ,使用观察者模式来实现数据绑定和响应式更新。当数据发生变化时,框架会通知相关的观察者组件,使其自动更新视图。

5. \color{red}{5.} 5. WebSocket 通信 :WebSocket 是一种双向通信协议,利用观察者模式来实现实时消息推送。服务器 可以作为主题 ,而客户端 则充当观察者。当服务器有新消息时,它会通知所有连接的客户端。

6. \color{red}{6.} 6. Node.js 事件驱动编程 :Node.js 是基于事件驱动的非阻塞 I/O 模型。它使用观察者模式来处理事件 和回调函数。当特定的事件发生时,Node.js 会通知相应的观察者执行对应的回调函数,以实现异步和并发操作。

7. \color{red}{7.} 7. 第三方库 :MobX 是一个 JavaScript 库,用于管理状态(state)和处理状态变化。它使用了观察者模式来跟踪对状态 的更改,并使得相关组件能够自动地进行更新。

ES6 Observers

ES6 中引入了五种 Observer,可以看成是对订阅者模式的实践,它们分别为:

1. \color{red}{1.} 1. ResizeObserver:用于监测元素尺寸变化。

2. \color{red}{2.} 2. MutationObserver:用于监测 DOM 树的变化。

3. \color{red}{3.} 3. ReportingObserver:用于监测报告类型的变化。

4. \color{red}{4.} 4. PerformanceObserver:用于监测页面性能指标。

5. \color{red}{5.} 5. IntersectionObserver:用于监测元素是否进入视口或与其交叉。

对于上面的这五个 Observer 的使用,我会在下一篇文章中介绍!

相关推荐
java1234_小锋4 小时前
【技术专题】HTML5 网页技术 - HTML5 Canvas 基础以及动画入门
前端·html·html5
知了学历孙老师7 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
ShineWinsu9 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说9 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
高晶11 小时前
无乘法器实现LC二阶滤波器:基于移位运算的快速算法与四种精度推导
算法·设计模式·程序员
程序员老赵11 小时前
Docker 部署青龙面板:轻松搭建定时任务管理平台
前端·docker·开源
Swot11 小时前
Asciidoctor 公式数字下标错位问题:原因分析与解决方案
前端
Swot11 小时前
leo-editor 中将 Markdown 内容转成 asciidoc 格式
前端
高晶11 小时前
主从自动分配算法:平均值乘以设备数一半的选举基准值解析
算法·设计模式·程序员
狒狒AI12 小时前
Remotion / GSAP+Three / HyperFrames / Skia 四栈实测:代码渲染知识视频的选栈方法(附开源技能)
前端·人工智能·aigc