JS设计模式之访问者模式

ops/2024/12/18 14:59:13/

前言

访问者模式(Visitor Pattern)是一种 行为设计模式,它允许在不改变对象结构的情况下,定义新的操作。

这种模式通过将操作封装在访问者对象中,使得可以在不修改被访问对象的情况下,增加新的功能。

本文将详细介绍访问者模式的主要组成部分、工作原理、优点、缺点、应用场景,并提供一个简单的 JavaScript 代码示例。

主要组成部分

1、 访问者(Visitor):定义一个访问接口,声明对每个具体元素的访问方法。每个具体访问者实现这个接口,以提供对不同元素的具体操作。

2、 元素(Element):定义一个接受访问者的方法,通常是一个 accept 方法,接受一个访问者作为参数。

3、具体元素(Concrete Element):实现元素接口,定义具体的元素对象,并实现 accept 方法,调用访问者的相应方法。

4、 对象结构(Object Structure):维护一组元素,通常是一个集合,提供一个方法来接受访问者。

工作原理

1、 客户端创建一个访问者对象和一个对象结构。

2、 对象结构遍历其元素,并将访问者传递给每个元素的 accept 方法。

3、 每个元素调用访问者的相应方法,从而实现对元素的操作。

优点

开放/关闭原则:可以在不修改现有元素类的情况下,添加新的操作,符合开放/关闭原则。

集中操作:将操作集中在访问者中,便于管理和维护。

缺点

增加复杂性:引入访问者模式可能会增加系统的复杂性,特别是在元素类较多时。

不易扩展元素:如果需要添加新的元素类,必须修改所有访问者接口,可能导致代码的修改和维护成本增加。

应用场景

1、编译器和解释器:用于语法树的遍历。

2、对象结构的操作:对一组对象执行多种操作。

3、图形编辑器:对不同形状执行操作。

4、数据结构的遍历:在复杂的数据结构中遍历和操作节点。

5、报告生成:生成不同类型的报告。

6、对象的状态检查:对一组对象进行状态检查。

7、游戏开发:对游戏对象执行操作。

8、数据转换:将不同格式的数据转换为目标格式。

代码示例

javascript">// 访问者接口
class Visitor {  visitConcreteElementA(element) {  console.log(`Visiting ConcreteElementA: ${element.operationA()}`);  }  visitConcreteElementB(element) {  console.log(`Visiting ConcreteElementB: ${element.operationB()}`);  }  
}  // 元素接口
class Element {  accept(visitor) {}  
}  // 具体元素A
class ConcreteElementA extends Element {  accept(visitor) {  visitor.visitConcreteElementA(this);  }  operationA() {  return 'Operation A';  }  
}  // 具体元素B
class ConcreteElementB extends Element {  accept(visitor) {  visitor.visitConcreteElementB(this);  }  operationB() {  return 'Operation B';  }  
}  // 对象结构
class ObjectStructure {  constructor() {  this.elements = [];  }  addElement(element) {  this.elements.push(element);  }  accept(visitor) {  for (const element of this.elements) {  element.accept(visitor);  }  }  
}  // 使用访问者模式
const visitor = new Visitor();  
const objectStructure = new ObjectStructure();  objectStructure.addElement(new ConcreteElementA());  
objectStructure.addElement(new ConcreteElementB());  objectStructure.accept(visitor);

总结

访问者模式非常适合用于需要对一组对象执行多种操作的场景,尤其是在对象结构相对稳定,而操作频繁变化的情况下。

它提供了一种灵活的方式来管理操作,使得系统更加模块化和可维护。

通过将操作封装在访问者对象中,我们可以在不修改现有对象结构的情况下,轻松地添加新的操作,从而提高代码的可扩展性和可维护性。

– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。


http://www.ppmy.cn/ops/142938.html

相关文章

Git简介和特点

目录 一、Git简介 二、Git特点 1.集中式和分布式 (1)集中式版本控制系统 (2)分布式版本控制系统 2.版本存储方式的差异 (1)直接记录快照,而非差异比较 3.近乎所有操作都是本地执行 一、Git简介 Git是目前世界上最先进的的分布式控制系统(没有之一…

【机器学习】在向量的流光中,揽数理星河为衣,以线性代数为钥,轻启机器学习黎明的瑰丽诗章

文章目录 线性代数入门:机器学习零基础小白指南前言一、向量:数据的基本单元1.1 什么是向量?1.1.1 举个例子: 1.2 向量的表示与维度1.2.1 向量的维度1.2.2 向量的表示方法 1.3 向量的基本运算1.3.1 向量加法1.3.2 向量的数乘1.3.3…

OpenShift 4 - 多云管理(2) - 配置多集群观察功能

《OpenShift / RHEL / DevSecOps 汇总目录》 本文在 OpenShift 4.17 RHACM 2.12 环境中进行验证。 文章目录 多集群观察技术架构安装多集群观察功能监控多集群的运行状态监控多集群的应用运行在被管集群监控应用运行在管理集群监控被管集群的应用运行 参考 多集群观察技术架构…

CSDN博客:如何使用Python的`datasets`库转换音频采样率

CSDN博客:如何使用Python的datasets库转换音频采样率 什么是采样率?代码用途:调整音频数据的采样率完整代码示例代码详解运行结果(示例)总结 在这篇文章中,我们将学习如何使用Python的datasets库对音频数据…

ios swift 开发系列--如何把粤语转语音

在Swift中,我们可以使用AVSpeechSynthesizer进行文本到语音的转换,我们通过设置AVSpeechUtterance的voice属性来指定朗读的语言和口音。 要确保朗读的是粤语,我们应该使用一个特定的语言代码,例如"zh-Hant-HK"&#xf…

Python+OpenCV系列:膨胀和腐蚀——图像形态学操作深度解析

文章目录 什么是膨胀(Dilation)?什么是腐蚀(Erosion)?膨胀和腐蚀如何工作?如何在Python中使用OpenCV实现膨胀和腐蚀?**1. 图像膨胀****2. 图像腐蚀****3. 膨胀与腐蚀的组合使用****调…

【JavaEE初阶】线程 和 thread

本节⽬标 认识多线程 掌握多线程程序的编写 掌握多线程的状态 一. 认识线程(Thread) 1概念 1) 线程是什么 ⼀个线程就是⼀个 "执⾏流". 每个线程之间都可以按照顺序执⾏⾃⼰的代码. 多个线程之间 "同时" 执⾏着多份代码. 还…

SQL 中的 JOIN(JOIN 简化与提速系列 1)

连接运算(JOIN)一直是 SQL 中的老大难问题。在关联表稍多一点的时候,代码书写就变得很容易出错了。而且因为 JOIN 语句的复杂,导致关联查询也一向是 BI 软件的软肋,几乎没有 BI 软件能让业务用户顺畅地完成多表关联查询…