前端开发的观察者模式

news2024/11/12 13:51:23

什么是观察者设计模式

观察者模式(Observer Pattern)是前端开发中常用的一种设计模式。它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其所有依赖对象都能收到通知并自动更新。观察者模式广泛应用于事件驱动的系统,如浏览器事件、发布-订阅系统,以及各类框架的状态管理机制。

观察者设计模式定义了一种 一对多 的依赖关系,当 一个对象的状态发生变化 时,所有依赖它的对象都会自动收到通知。这种模式可以解耦观察者和被观察者,使得它们可以独立变化。

观察者模式的关键角色:

  1. Subject(被观察者): 负责维护观察者列表,并在自身状态发生变化时通知所有观察者。
  2. Observer(观察者): 订阅目标的变化,并在收到通知时执行相关操作。

观察者模式的实现

1. 简单观察者模式

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

// 被观察者
class Subject {
  private observers: Observer[] = [];
  private state: string = '';

  // 添加观察者
  public attach(observer: Observer): void {
    this.observers.push(observer);
  }

  // 移除观察者
  public detach(observer: Observer): void {
    this.observers = this.observers.filter(obs => obs !== observer);
  }

  // 通知所有观察者
  public notify(): void {
    this.observers.forEach(observer => observer.update(this.state));
  }

  // 改变状态并通知观察者
  public setState(state: string): void {
    this.state = state;
    this.notify();
  }
}

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

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

  // 收到通知时的动作
  public update(state: string): void {
    console.log(`${this.name} received update: ${state}`);
  }
}

// 测试观察者模式
const subject = new Subject();

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

subject.attach(observer1);
subject.attach(observer2);

subject.setState('State A');
subject.setState('State B');

在这个例子中,我们实现了基本的观察者模式:一个 Subject 类可以被多个 Observer 观察,每当 Subject 的状态发生变化时,它会通知所有观察者。

2. 发布-订阅模式

发布-订阅模式(Publish-Subscribe Pattern) 是观察者模式的一种变体,通常通过事件系统来实现。发布者不直接通知观察者,而是通过中介(消息中心)将事件广播出去,由订阅者选择性地接收。

// 消息中心
class EventEmitter {
  private events: { [key: string]: Function[] } = {};

  // 订阅事件
  public subscribe(event: string, listener: Function): void {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(listener);
  }

  // 发布事件
  public publish(event: string, data?: any): void {
    if (this.events[event]) {
      this.events[event].forEach(listener => listener(data));
    }
  }

  // 取消订阅
  public unsubscribe(event: string, listener: Function): void {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(l => l !== listener);
    }
  }
}

// 测试发布-订阅模式
const eventEmitter = new EventEmitter();

const handler = (data: any) => console.log('Event received:', data);

// 订阅事件
eventEmitter.subscribe('eventA', handler);

// 发布事件
eventEmitter.publish('eventA', { message: 'Hello, World!' });

// 取消订阅
eventEmitter.unsubscribe('eventA', handler);

在发布-订阅模式中,发布者和订阅者是通过 EventEmitter 消息中心进行通信的,发布者无需知道订阅者的存在,这使得它们之间的耦合度进一步降低。

3. 双向绑定模式(MVVM)

MVVM(Model-View-ViewModel) 是一种常见的双向绑定模式,在前端框架如 VueAngular 中很常见。它通过数据绑定使得 ViewModel 可以双向通信,通常是通过一个 ViewModel 来桥接二者。

// ViewModel
class ViewModel {
  private state: string = '';
  private observers: Function[] = [];

  // 获取当前状态
  public getState(): string {
    return this.state;
  }

  // 设置状态并通知视图更新
  public setState(newState: string): void {
    this.state = newState;
    this.notify();
  }

  // 添加视图更新的回调
  public bind(observer: Function): void {
    this.observers.push(observer);
  }

  // 通知视图更新
  private notify(): void {
    this.observers.forEach(observer => observer(this.state));
  }
}

// 视图更新函数
const updateView = (state: string) => {
  console.log('View updated:', state);
};

// 测试双向绑定
const viewModel = new ViewModel();
viewModel.bind(updateView);

viewModel.setState('New State');
console.log('Current State:', viewModel.getState());

在这个例子中,ViewModel 充当了模型和视图之间的桥梁,确保视图在数据更新时及时反应。这是 MVVM 模式的一个简单实现。

总结

观察者设计模式及其变体在前端开发中起着至关重要的作用。通过观察者模式,可以解耦对象之间的直接依赖关系,从而提升系统的灵活性和可维护性。无论是基础的观察者模式,还是更为复杂的发布-订阅模式、双向绑定模式,都在不同的场景中发挥了不可替代的作用。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

56页PPT | 大数据决策分析平台怎么建设?经典实践方案推荐

一、现状和目标 企业用户现状:数据分散,利用率低,业务需求变化快但IT响应慢。 问题:数据展示不及时、不准确,缺乏深入分析工具,报表制作效率低下。 目标:建设统一的数据整合平台,…

四款数据恢复精灵好用之处及使用感受~

在数字化的时代,数据的重要性不言而喻;不慎删除重要文件、格式化磁盘后数据丢失、存储设备故障……这些情况都可能让我们痛心疾首;这时,数据恢复软件就显得尤为重要了,今天,就为大家介绍四款备受好评的数据…

服装|基于Java+vue的服装定制系统(源码+数据库+文档)

服装定制系统 目录 基于Javavue的服装定制系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布…

Linux——redis主从复制、集群模式、哨兵模式

主从复制 部署至少两个redis的实例 // 提供数据冗余和备份 两个独立服务器两个虚拟机两个容器一个redis的master 节点可以有多个redis的replica 从节点, 而从节点也可以成为其他从节点的主节点 // 方便对于主复制架构进行扩展提供数据灾备,当red…

复赛总榜TOP1方案Champion Chasing Boy分享

关联比赛: 2020数字中国创新大赛—算法赛:智慧海洋建设 写在前面的话 大家好,我是 Champion Chasing Boy的DOTA,在队友 鱼遇雨欲语与余、 尘沙杰少、林有夕、嗯哼哼唧 的Carry下,最终在本届智能算法赛拿到了复赛总榜单Top1的成绩…

Java通过jna调用c++动态库

1、pom文件添加jna依赖 <dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.14.0</version></dependency> 2、注意问题 要实现Java调用C的动态库&#xff0c;需要使用"extern C&…

Script-server: 一款开源的脚本管理工具,为你的Python脚本提供一个直观的 Web UI

在日常工作中&#xff0c;我们经常会使用各种脚本来自动化任务&#xff0c;提升效率。但传统的脚本管理方式往往伴随着一些困扰&#xff1a;复杂的命令行操作、难以理解的脚本参数、缺乏直观的反馈等等。这些问题&#xff0c;让原本应该便捷的脚本管理变得繁琐。 Script-server…

Qt-QWidget的focusPolicy属性(20)

目录 描述 相关API 使用 描述 这里引入了焦点的概念&#xff0c;这个很重要&#xff0c;也是伴随后面介绍中的一个很重要的概念 拿魔兽世界来举例&#xff0c;如下我们在操作兵种的时候&#xff0c;需要先选中单位&#xff0c;然后才能对这些单位进行命令的下达 这一点在笔…

[极客大挑战 2019]Http

1、访问题目链接 2、查看页面源码发现一个Secret.php的跳转页面 3、访问Secret.php发现页面有提示&#xff0c;它说它不是来自这个网页 4、抓包修改来源 添加&#xff1a;Referer: https://Sycsecret.buuoj.cn 发送查看响应 5、修改User-Agent为&#xff1a;Syclover 6、添加X-…

Catia的插件不能调用CAA 的API问题

今天到客户实施Catia二开软件&#xff0c;发现在客户的电脑上调用CAA的API出现调用失败的问题。 根据经验&#xff0c;想到大概是用户电脑上的Catia授权有问题&#xff0c;但是Catia的一大堆授权中需要哪些授权呢&#xff0c;最后花了半天的时间使用二分法测试出&#xff0c;C…

产线工控安全之防勒索病毒杀手锏

在当今数字化时代&#xff0c;数据安全已成为企业运营中不可或缺的一部分。勒索病毒和内部泄密事件的频发&#xff0c;使得企业必须采取更为严格的安全措施来保护其关键数据和运营系统。苏州深信达网络科技推出的MCK主机加固解决方案&#xff0c;正是为了应对这些挑战而设计的。…

十三、创建Uss血条样式

一、控制StyleSheet 1、点击左上角USS文件&#xff08;创建&#xff09; 2、双击style里面的黄色progress-bar 3、在USS文件夹中添加代码实现 4、在主UI上有一个margin&#xff08;外&#xff09;和padding(里) 在Spacing中进行修改 5、只有文字可以在这里进行修改 6、在Atrib…

车载以太网之SOME/IP

整体介绍 SOME/IP(全称为:Scalable service-Oriented MiddlewarE over IP),是运行在车载以太网协议栈基础之上的中间件,或者也可以称为应用层软件。 ​发展历程 AUTOSAR 4.0 - 完成宝马SOME/IP消息的初步集成;AUTOSAR 4.1 - 支持SOME/IP-SD及其发布/订阅功能;AUTOSAR 4.…

自动驾驶相关的理论基础

本文主要参考论文《基于计算机视觉和深度学习的自动驾驶方法研究_白辰甲》&#xff0c;记录一些理论知识。 自动驾驶定义 自动驾驶是指车辆通过传感器感知周围环境&#xff0c;在没有人为干预的情况下&#xff0c;实时改变驾驶行为&#xff0c;完成驾驶任务。 基于计算机视觉…

在树莓派上构建和部署 Node.js 项目

探索在Raspberry Pi上构建和部署Node.js项目的最佳实践。通过我们的专业提示和技巧&#xff0c;克服常见挑战&#xff0c;使您的项目顺利运行。 去年圣诞节&#xff0c;我收到了一份极其令人着迷的礼物&#xff0c;它占据了我许多周末的时间&#xff0c;甚至让我夜不能寐。它就…

SpringBoot打包部署,打包成jar和war有所不同?

1. 我的一个springboot项目&#xff0c;用mvn install打包成jar&#xff0c;换一台有jdk的机器就直接可以用java -jar 项目名.jar的方式运行&#xff0c;没任何问题&#xff0c;为什么这里不需要tomcat也可以运行了&#xff1f; 2. 然后我打包成war放进tomcat运行&#xff0c;…

云服务器部署DB-GPT项目

本文收录于《DB-GPT项目》专栏&#xff0c;专栏总目录&#xff1a; 点击这里。 文章目录 项目介绍 一、登录云服务器 1. 进入控制台 2.点击容器实例&#xff08;点数字&#xff09; 二、创建容器实例 1. 等待容器实例创建好&#xff0c;创建好的容器实例如下&#xff1a;…

多个微信是怎么进行管理的?

随着微信逐渐成为企业商务沟通的重要平台&#xff0c;对于业务咨询量较大的行业&#xff08;例如教育培训、旅游、美容以及医疗等&#xff09;而言&#xff0c;在利用微信进行营销活动和客户服务的过程中&#xff0c;往往会遭遇多微信管理的困境。 在此情形下&#xff0c;选用工…

fwt变换模板

在算法竞赛中&#xff0c;FWT 是用于解决对下标进行位运算卷积问题的方法。 公式&#xff1a; 1.ij|k(j,k相或等于i) void Or(ll * a, ll type) { // 迭代实现&#xff0c;常数更小 for (ll x 2; x < n; x << 1) { ll k x >> 1; …

C++ 在项目中使用Git

目录 一&#xff1a;配置邮箱和姓名 二&#xff1a;生成SSH Key 三&#xff1a;git 工作区和状态 四&#xff1a;git log 常用法 五&#xff1a;git diff 常用法 六&#xff1a;git 分支操作 七&#xff1a;git 回溯分支 八&#xff1a;git rebase -i 压缩历史提交…