TypeScript 设计模式之【观察者模式】

news2024/9/27 16:18:31

文章目录

  • 观察者模式:构建灵活响应的事件通知系统
  • 观察者模式的奥秘
    • 观察者模式有什么利与弊?
    • 如何使用观察者模式来优化你的系统
    • 代码实现案例
    • 观察者模式的主要优点
    • 观察者模式的主要缺点
    • 观察者模式的适用场景
    • 总结

在这里插入图片描述

观察者模式:构建灵活响应的事件通知系统

每当有订阅热点事件发生时,你都会立即收到通知。这个过程中,你就像一个"观察者",而热点事件应用则是"被观察者"。这种实时更新的机制,正是观察者模式的生动体现。

软件开发中,我们经常需要处理对象之间的一对多依赖关系,一个对象状态改变时,所有依赖于它的对象都能得到通知并自动更新。观察者模式类似一个智能的通知系统,能够在保持对象之间松耦合的同时,灵活处理事件!

观察者模式的奥秘

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式有什么利与弊?

观察者模式的优点是它支持广播通信,增加了灵活性和可扩展性。它遵循开闭原则,使得我们可以在不修改现有代码的情况下添加新的观察者。缺点是如果处理不当,会引起性能问题和循环依赖。

如何使用观察者模式来优化你的系统

观察者模式涉及角色

  • 主题(Subject): 定义添加、删除和通知观察者的接口
  • 具体主题(ConcreteSubject): 实现主题接口,维护观察者列表,发生变化时通知观察者
  • 观察者(Observer): 定义一个更新接口,使在主题状态变化时得到通知
  • 具体观察者(ConcreteObserver): 实现观察者更新接口,以便在得到通知时进行自我更新

观察者模式步骤

  1. 创建一个主题接口,定义添加、删除和通知观察者的方法
  2. 创建一个观察者接口,定义更新方法
  3. 实现具体主题类,维护观察者列表,实现通知逻辑
  4. 实现具体观察者类,定义在收到通知时的具体行为
  5. 在主题状态改变时,通知所有注册的观察者

选择合适的观察者模式,你就能轻松地实现对象之间的解耦,让系统变得更加灵活和可扩展!

代码实现案例

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

// 主题接口
interface Subject {
  // 附加
  attach(observer: Observer): void;
  // 脱离
  detach(observer: Observer): void;
  // 通知
  notify(message: string): void;
}

// 具体主题:新闻发布者
class NewsPublisher implements Subject {
  private observers: Observer[] = [];

  attach(observer: Observer): void {
    const isExist = this.observers.includes(observer);
    if (isExist) {
      return console.log("观察者已经存在,无需重复添加");
    }
    this.observers.push(observer);
    console.log("观察者已添加");
  }

  detach(observer: Observer): void {
    const observerIndex = this.observers.indexOf(observer);
    if (observerIndex === -1) {
      return console.log("未找到要删除的观察者");
    }
    this.observers.splice(observerIndex, 1);
    console.log("观察者已被移除");
  }

  notify(message: string): void {
    console.log("通知所有观察者");
    for (const observer of this.observers) {
      observer.update(message);
    }
  }

  publishNews(news: string): void {
    console.log(`发布新闻: ${news}`);
    this.notify(news);
  }
}

// 具体观察者:新闻订阅者
class NewsSubscriber implements Observer {
  private name: string;

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

  update(message: string): void {
    console.log(`${this.name} 收到新闻: ${message}`);
  }
}
// 客户端代码
const publisher = new NewsPublisher();

const subscriber1 = new NewsSubscriber("张三");
const subscriber2 = new NewsSubscriber("李四");
const subscriber3 = new NewsSubscriber("王五");

publisher.attach(subscriber1);
publisher.attach(subscriber2);
publisher.attach(subscriber3);

publisher.publishNews("中国成功发射神舟十八号载人飞船!");

publisher.detach(subscriber2); // 李四通知被移除

publisher.publishNews("2023年高考开始了!");

// 输出
// 观察者已添加
// 观察者已添加
// 观察者已添加
// 发布新闻: 中国成功发射神舟十八号载人飞船!
// 通知所有观察者
// 张三 收到新闻: 中国成功发射神舟十八号载人飞船!
// 李四 收到新闻: 中国成功发射神舟十八号载人飞船!
// 王五 收到新闻: 中国成功发射神舟十八号载人飞船!
// 观察者已被移除
// 发布新闻: 2023年高考开始了!
// 通知所有观察者
// 张三 收到新闻: 2023年高考开始了!
// 王五 收到新闻: 2023年高考开始了!

在这里插入图片描述

观察者模式的主要优点

  1. 松耦合: 主题和观察者之间是松散耦合的,它们依然可以独立地改变
  2. 支持广播通信: 主题无需知道观察者的具体类,只需通知所有观察者
  3. 灵活性和可扩展性: 可以动态地增加或删除观察者,无需修改主题
  4. 符合开闭原则: 无需修改主题就可以引入新的观察者类

观察者模式的主要缺点

  1. 引起性能问题: 如果观察者数量太多,通知所有观察者会花费较多时间
  2. 导致循环依赖: 观察者和主题之间可能出现循环依赖
  3. 通知次序不可控: 不保证通知顺序,可能导致不一致的状态
  4. 意外的更新: 如果观察者之间有依赖关系,可能导致意外的更新

观察者模式的适用场景

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时
  2. 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变时
  3. 当一个对象必须通知其他对象,而它又不能假定其他对象是谁时
  4. 需要在系统中创建一个触发链时

总结

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者都会得到通知并自动更新。观察者模式通过解耦主题和观察者,提高了系统的灵活性和可扩展性。合理使用观察者模式,可以让你的代码更加模块化,更易于维护和扩展。

喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!

下期预告: TypeScript 设计模式之【状态模式】

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

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

相关文章

Mortise AI编程智能体产品 | OPENAIGC开发者大赛企业组AI创作力奖

在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…

华为 HCIP-Datacom H12-821 题库 (28)

🐣博客最下方微信公众号回复题库,领取题库和教学资源 🐤诚挚欢迎IT交流有兴趣的公众号回复交流群 🦘公众号会持续更新网络小知识😼 1.使用 NAT 技术,只可以对数据报文中的网络层信息(IP 地址&#xff09…

贴片式TF卡(SD NAND)参考设计

【MK 方德】贴片 TF 卡参考设计 一、电路设计 1、 参考电路: R1~R5 (10K-100 kΩ)是上拉电阻,当 SD NAND 处于高阻抗模式时,保护 CMD 和 DAT 线免受总线浮动。 即使主机使用 SD NAND SD 模式下的 1 位模式,主机也应通过上拉电阻…

Type-C接口桌面显示器的优势

随着科技的飞速发展,电子设备的连接性、便捷性和高效性成为了消费者关注的重点。在这个背景下,Type-C接口桌面显示器以其卓越的性能和广泛的兼容性,正逐步成为市场上的主流选择。本文将深入探讨Type-C接口桌面显示器的优势、应用场景、市场现…

【大模型-驯化】成功解决载cuda-11.8配置下搭建swift框架

【大模型-驯化】成功解决载cuda-11.8配置下搭建swift框架 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 相关内容文档获取 微信公众号 &…

传奇微端黑屏不更新地图?传奇微端架设教程——GOM引擎

登录器和网站配置好后,我们进入游戏后会发现是黑屏的,更新不了地图和NPC这些,因为还没有做微端,会黑屏也是正常的。有些老G做了微端但是还是黑屏,就可能是你的微端架设出现了问题,可以参考以下教程。 gom引…

顶顶通呼叫中心中间件-机器人话术挂机后是否处理完成事件

前言 问题:机器人放音的过程中,如果用户直接挂机就会继续匹配下一个流程,如果匹配上的是放音节点,还会进行放音,那么在数据库表中就会多出一条放音记录。 解决方法 一、话术添加一个全局挂机节点 需要在话术中添加一…

多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测(Matlab)

多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测 目录 多维时序 | GWO-VMD-SSA-LSTM灰狼优化变分模态分解联合麻雀优化长短期记忆网络多变量时间序列光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 …

python-4-4-编程规范2

str1 ,str2 input("请输入两个学生的姓名,用空格分开").split() print(str1) print(str2)print("hello python")name "Jim" print("His name is :",name)a "hello" b "python" print(a,b)print(&q…

如何搭建自动化测试框架(完整版)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 最近好多小伙伴都在说接口自动化测试,那么究竟什么是接口自动化测试呢?让我们一起往下看就知道了,首先我们得先弄清楚下面这个问…

做谷歌seo,什么是合理的谷歌url结构?

合理的URL结构至关重要,它不仅影响搜索引擎的索引效果,还直接关系到用户的浏览体验,跟国内做seo不同,链接里的英文也是能作为关键词使用的,谷歌不仅依赖于页面内容来判断页面相关性,URL中的文字也能为其提供…

招联金融秋招-2025

【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策划 产品运营…

飞轮科技携手观测云亮相云栖大会,全方位展示阿里云数据库 SelectDB 版核心优势

9 月 19 日 - 21 日,以「云启智跃,产业蝶变」为主题的阿里云 2024 云栖大会在杭州云栖小镇顺利举办。大会设有三大主论坛、400 多个分论坛,并开放 4 万平方米的智能科技展区。作为中国云计算产业链的年度盛会,云栖大会已连续举办 …

unity 打包安卓 RenderTexture显示红色

1、ColorFarmat: 每个图形卡可能并不支持跨格式的所有用法。使用 SystemInfo.IsFormatSupported 可以检查图形卡支持的用法。 None未指定格式。R8G8B8A8_UNorm一种四分量、32 位无符号归一化格式,在字节 0 中具有 8 位 R 分量,在字节 1 中具…

算法-分治和逆序

分治法(Divide and Conquer)是一种重要的算法设计范式,它通过将复杂的问题分解成更小、更易于管理和解决的子问题,然后递归地解决这些子问题,最后将子问题的解合并以得到原问题的解。分治法通常用于排序、搜索、数学计…

Centos怎么执行脚本

方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本 cd /data/shell ./hello.sh 方法二:以绝对路径的方式去执行bash shell脚本 /data/shell/hello.sh 方法三:直接使用bash 或sh 来执行…

消费类摄像头热销海内外,萤石出货量全球排名第一

随着消费者对家庭安全、便捷生活的需求日益增长,智能摄像头作为智能家居的重要组成部分,其市场需求将持续扩大。 IDC《全球智能家居设备市场季度跟踪报告,2024年第二季度》显示,二季度全球智能摄像头市场(包含消费级室…

足球预测模型理论:足球数据分析——XGBoost算法实战

简介:本文将探讨如何使用XGBoost算法进行足球数据分析,特别是足球运动员身价估计。我们将通过实例和生动的语言,解释XGBoost算法的原理和实际应用,帮助读者理解复杂的技术概念,并提供可操作的建议和解决问题的方法。 足…

ML 系列:机器学习和深度学习的深层次总结(04)多元线性回归 (MLR)

图 1.多元线性回归与简单线性回归 一、说明 线性回归从一维推广到多维,这与单变量线性回归有很多不同,情况更加复杂,而在梯度优化也需要改成向量梯度,同时,数据预处理也成了必要步骤。 二、综述 多元线性回归是简单线性…

基于flask常见trick——unicode进制编码绕过

前言 Flask 是一个轻量级的 Python Web 框架,设计上追求简洁和灵活性,适合构建中小型的 Web 应用程序。 其出题方便,经常能在CTF比赛中见到,常见题型有debug模式算pin码、ssti、原型链污染等,其中后两者属于通用漏洞…