JS设计模式之访问者模式

前言

访问者模式(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);

总结

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

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

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

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

相关推荐
浅水壁虎17 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥17 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
mONESY18 小时前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔18 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
gis开发之家19 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
bloglin9999920 小时前
langchain 和 langgraph 和 react
javascript·react.js·langchain
触底反弹20 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
会周易的程序员1 天前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm
带娃的IT创业者1 天前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc
新中地GIS开发老师1 天前
零基础WebGIS开发入门 | GeoJSON数据持久化
前端·javascript·gis·webgis·三维gis开发