TypeScript 设计模式之【访问者模式】

news2024/9/29 15:50:23

文章目录

  • 访问者模式:灵活的文件系统扫描器
  • 访问者模式的奥秘
    • 访问者模式有什么利与弊?
    • 如何使用访问者模式来优化你的系统
    • 代码实现案例
    • 访问者模式的主要优点
    • 访问者模式的主要缺点
    • 访问者模式的适用场景
    • 总结

在这里插入图片描述

访问者模式:灵活的文件系统扫描器

假如你正在开发一个文件系统扫描器,需要对不同类型的文件执行不同的操作: 统计文本文件的字数,计算图片文件的大小,分析音频文件的时长。这个看似简单的文件处理任务,这就是访问者模式的精髓。

在软件开发中,我们经常遇到需要对一个复杂的对象结构中的所有元素执行某些操作的情况。访问者模式就像这个文件系统扫描器,它允许你在不改变各元素的类的前提下定义作用于这些元素的新操作。这种模式让你能够将数据结构和数据操作分离开来!

访问者模式的奥秘

访问者模式类似一个"灵活的文件处理器",在不修改现有类结构的情况下,为一组类增加新的操作。你可以将数据结构和数据操作分离,使得系统更加灵活和可扩展。

访问者模式有什么利与弊?

访问者模式的优点是它能够在不修改现有类的情况下定义新的操作,使得系统更容易扩展。它还能将相关的操作集中到一个访问者对象中,而不是分散在各个类中。缺点是增加新的元素类比较困难,因为需要修改所有现有的访问者。

如何使用访问者模式来优化你的系统

访问者模式涉及角色

  • 访问者(Visitor): 声明了一个或多个访问操作方法
  • 具体访问者(ConcreteVisitor): 实现了访问者声明的操作
  • 元素(Element): 定义一个接受访问者的方法
  • 具体元素(ConcreteElement): 实现了元素接口
  • 对象结构(ObjectStructure): 能够枚举它的元素,可以提供一个高层的接口让访问者访问它的元素

访问者模式步骤

  1. 创建一个访问者接口,为每种具体元素类声明一个访问操作
  2. 创建具体访问者类,实现访问者接口中的操作
  3. 在元素接口中声明一个接受访问者的方法
  4. 在具体元素类中实现接受访问者的方法
  5. 创建对象结构类,该类可以遍历所有元素

选择合适的访问者模式,你就能轻松地为复杂的对象结构添加新的操作,让系统变得更加灵活和可维护!

代码实现案例

// 访问者接口-文件访问
interface FileVisitor {
  // 文本访问
  visitTextFile(file: TextFile): void;
  //  图片访问
  visitImageFile(file: ImageFile): void;
  // 音频访问
  visitAudioFile(file: AudioFile): void;
}

// 元素接口- 文件
interface File {
  accept(visitor: FileVisitor): void;
}

// 具体元素类 - 文本文件
class TextFile implements File {
  constructor(public name: string, public content: string) {}

  accept(visitor: FileVisitor): void {
    visitor.visitTextFile(this);
  }
}

// 具体元素类 - 图片文件
class ImageFile implements File {
  constructor(public name: string, public size: number) {}

  accept(visitor: FileVisitor): void {
    visitor.visitImageFile(this);
  }
}

// 具体元素类 - 音频文件
class AudioFile implements File {
  constructor(public name: string, public duration: number) {}

  accept(visitor: FileVisitor): void {
    visitor.visitAudioFile(this);
  }
}

// 具体访问者类 - 文件统计
class FileStatisticsVisitor implements FileVisitor {
  private textFileCount = 0;
  private imageFileCount = 0;
  private audioFileCount = 0;

  visitTextFile(file: TextFile): void {
    this.textFileCount++;
  }

  visitImageFile(file: ImageFile): void {
    this.imageFileCount++;
  }

  visitAudioFile(file: AudioFile): void {
    this.audioFileCount++;
  }

  printStatistics(): void {
    console.log(`文本文件数量: ${this.textFileCount}`);
    console.log(`图片文件数量: ${this.imageFileCount}`);
    console.log(`音频文件数量: ${this.audioFileCount}`);
  }
}
// 具体访问者类 - 文件详情
class FileDetailsVisitor implements FileVisitor {
  visitTextFile(file: TextFile): void {
    console.log(
      `文本文件: ${file.name}, 内容长度: ${file.content.length} 字符`
    );
  }

  visitImageFile(file: ImageFile): void {
    console.log(`图片文件: ${file.name}, 大小: ${file.size} KB`);
  }

  visitAudioFile(file: AudioFile): void {
    console.log(`音频文件: ${file.name}, 时长: ${file.duration}`);
  }
}

// 对象结构类 - 文件系统
class FileSystem {
  private files: File[] = [];

  addFile(file: File): void {
    this.files.push(file);
  }

  accept(visitor: FileVisitor): void {
    for (const file of this.files) {
      file.accept(visitor);
    }
  }
}
// 客户端代码
const fileSystem = new FileSystem();
fileSystem.addFile(new TextFile("readme.txt", "这是一个自述文件"));
fileSystem.addFile(new ImageFile("logo.png", 2048));
fileSystem.addFile(new AudioFile("song.mp3", 180));
fileSystem.addFile(new TextFile("document.txt", "这是一个文档文件"));

console.log("文件统计:");
const statisticsVisitor = new FileStatisticsVisitor();
fileSystem.accept(statisticsVisitor);
statisticsVisitor.printStatistics();

console.log("\n文件详情:");
const detailsVisitor = new FileDetailsVisitor();
fileSystem.accept(detailsVisitor);

// 输出
// 文件统计:
// 文本文件数量: 2
// 图片文件数量: 1
// 音频文件数量: 1

// 文件详情:
// 文本文件: readme.txt, 内容长度: 8 字符
// 图片文件: logo.png, 大小: 2048 KB
// 音频文件: song.mp3, 时长: 180 秒
// 文本文件: document.txt, 内容长度: 8 字符

在这里插入图片描述

访问者模式的主要优点

  1. 符合单一职责原则: 通过访问者将数据结构与数据操作分离
  2. 优秀的扩展性: 可以在不修改对象结构的情况下,轻松地增加新的操作
  3. 集中相关的操作: 将相关的操作集中到一个访问者对象中
  4. 对象结构变化较少: 适用于对象结构相对稳定,但经常需要在此结构上定义新的操作的系统

访问者模式的主要缺点

  1. 增加新的元素类困难: 每增加一个新的元素类,都需要在访问者中增加相应的方法
  2. 破坏封装: 访问者模式通常需要对象结构开放内部数据给访问者
  3. 违反依赖倒置原则: 访问者依赖于具体元素类型

访问者模式的适用场景

  1. 对象结构中包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作"污染"这些对象的类
  3. 对象结构很少改变,但经常需要在此结构上定义新的操作

总结

访问者模式是一种行为型设计模式,它允许你在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式通过将数据结构与数据操作分离,实现了优秀的扩展性。这种模式在处理复杂对象结构时特别有用,能够让你的代码更加灵活和可维护。然而,它也带来了一些复杂性,在使用时需要权衡利弊。合理使用访问者模式,可以让你的代码结构更加清晰,更易于理解和维护。

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

自此: TypeScript 设计模式系列就更新完啦,大家感兴趣可以关注下,后面会出新的专栏,感谢大家的支持

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

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

相关文章

智能物流行业惨淡,工程师们的“灰色地带”收入揭秘

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 在智能物流行业面临挑战的当下,工程师们除了正职收入外,也在探索各种途径来增加自己的“额外收益”。 这些收入&…

微信小程序环境下的相亲交友系统源码优化

随着移动互联网的迅猛发展,微信小程序因其便捷性和易用性成为众多开发者的选择。在这样一个背景下,相亲交友系统作为连接人与人的桥梁,也逐渐融入到了小程序的生态之中。本文旨在探讨如何在微信小程序环境中优化相亲交友系统的源码&#xff0…

云计算Openstack Cinder

OpenStack Cinder是OpenStack平台中的一个重要组件,它主要提供块存储服务。 一、基本概念 定义:Cinder是OpenStack项目中的一个模块,专注于为云计算环境中的虚拟机提供持久化的块存储服务。功能:Cinder允许用户创建和管理持久化…

前端辅助工具分享(像素大厨)

引言: 我们在从事前端开发工作时,常会需要测量许多盒子的尺寸,颜色提取种种,切图,还有文字大小等信息,光从肉眼很难看出来,当然我们传统的会使用Photoshop来帮助我们完成这些工作,但…

LeetCode 第417场周赛个人题解

目录 Q1. 找出第 K 个字符 I 原题链接 思路分析 AC代码 Q2. 元音辅音字符串计数 I 原题链接 思路分析 AC代码 Q3. 元音辅音字符串计数 II 原题链接 思路分析 AC代码 Q4. 找出第 K 个字符 II 原题链接 思路分析 AC代码 Q1. 找出第 K 个字符 I 原题链接 Q1. 找出…

ethtool网络命令

1、ethtool命令描述 ethtool 是用于查询及设置网卡参数的命令。 2、查看网卡eth0信息 [rootes01 ~]# ethtool eth0 3、查看网络eth0速率 [rootmgr2 tmp]# ethtool -S eth0 4、设置网口 设置网口速率10/100/1000M、设置网口半/全双工、设置网口是否自协商 ethtool –s eth…

现在企业生存都困难,还谈什么数字化转型?

在当下经济大环境不好的情景下,经常听到如下论调:企业生存都困难,还谈什么数字化?这一论调反映了在当前经济环境下,一些企业对于数字化转型的疑虑和担忧,同时对数字化转型也缺乏正确的认知。下面笔者就上述论调进行简…

JAVA TCP协议初体验

文章目录 一、需求概述二、设计选择三、代码结构四、代码放送五、本地调试1. 服务端日志2. 客户端日志3. 断线重连日志 六、服务器部署运行1. 源码下载2. 打包镜像3. 运行容器 一、需求概述 最近开发某数据采集系统,系统整体的数据流程图如下: #mermaid…

聚观早报 | 淘宝已接入微信支付;Meta Orion AR眼镜发布

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 9月29日消息 淘宝已接入微信支付 Meta Orion AR眼镜发布 iQOO 13将登陆印度市场 小鹏汽车加码布局上海 哔哩哔哩…

电脑自带dll修复在哪里,dll丢失的6种解决方法总结

在现代科技日新月异的时代,电脑已经成为我们生活中不可或缺的一部分。然而,在使用电脑的过程中,我们常常会遇到一些常见的问题,其中之一就是dll文件丢失或损坏。当这些dll文件丢失或损坏时,可能会导致某些应用程序无法…

网络抓包03 - 实践篇

声明: 本文中提及的APK及相关内容仅用于学习和交流目的,不涉及任何商业用途。本文不鼓励或支持任何形式的版权侵犯行为,同时也强调对软件的安全使用。我们尊重和维护开发者的权益,强烈建议读者在使用软件时遵守相关法律法规&#…

烟雾检测算法、明烟明火检测、烟火识别算法

烟火检测是一种基于先进技术的安全监控手段,主要用于及时发现和预防火灾等安全事故。其技术原理和应用领域可以详细阐述如下: 技术原理 烟火检测算法主要依赖于计算机视觉、深度学习以及图像处理技术。具体步骤包括: 1、数据采集与预处理&…

jQuery——css

本文分享到此结束,欢迎大家评论区相互讨论学习,下一篇继续分享jQuery中offset 和 position的学习。

深度学习--------------------------------门控循环单元GRU

目录 门候选隐状态隐状态门控循环单元GRU从零开始实现代码初始化模型参数定义隐藏状态的初始化函数定义门控循环单元模型训练该部分总代码简洁代码实现 做RNN的时候处理不了太长的序列,这是因为把整个序列信息全部放在隐藏状态里面,当时间很长的话&#…

SpringCloud学习记录|day1

学习材料 2024最新SpringCloud微服务开发与实战,java黑马商城项目微服务实战开发(涵盖MybatisPlus、Docker、MQ、ES、Redis高级等) 学redis讲到微服务就停了,nginx也是。 所以嘛,我终于来到微服务了。 复习MyBatisP…

鸿蒙HarmonyOS开发生态

1、官网 华为开发者联盟-HarmonyOS开发者官网,共建鸿蒙生态 2、开发工具IDE下载及使用 https://developer.huawei.com/consumer/cn/ 3、使用帮助文档 4、发布到华为应用商店 文档中心

免费分享一套SpringBoot+Vue火车票订票管理系统【论文+源码+SQL脚本】,帅呆了~~

大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue火车票订票管理系统,分享下哈。 项目视频演示 【免费】SpringbootVue火车票订票管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 传统办法管理信息首先需要花费的时间比较多&…

CEX上币趋势分析:Infra赛道与Ton生态的未来

在当前的加密市场中,CEX(中心化交易所)上币的选择愈发重要,尤其是对项目方而言。根据 FMG 的整理,结合「杀破狼」的交易所上币信息,显然 Infra 赛道成为了交易所的热门选择,而 Ton 生态也展现出…

相互作用感知的 3D 分子生成 VAE 模型 - DeepICL 评测

DeepICL 是一个基于相互作用感知的 3D 分子生成模型,能够在目标结合口袋内进行相互作用引导的小分子设计。DeepICL 通过利用蛋白质-配体相互作用的普遍模式作为先验知识,在有限的实验数据下也能实现高度的泛化能力。 一、背景介绍 DeepICL 来源于韩国科学…

CHItrans简介--DVM

DVM基础flow 注:上图中,没有画出DVM指令对应的snoop request,相关snp请求如下所示: 对应的snp请求 Non-sync DVM trans flow Sync DVM trans flow Flow Control 后续的说明,参考: CHI协议之DVM操作_dvm r…