23 种设计模式中的访问者模式

server/2025/3/31 11:05:19/

主要用于在不改变对象结构的前提下,为对象结构中的元素添加新的操作。

访问者模式用于解决稳定数据结构和易变操作之间的耦合问题,设计的目的是不改变数据结构的定义,但允许增加新的访问者,来定义新的操作。

这里我们根据案例来具体学习访问者模式。以下是一个代码示例及知识点详解:

首先,我们要定义一个访问者接口:

java">// 1. 定义元素接口(被访问对象)
interface DocumentElement {void accept(DocumentVisitor visitor); // 接受访问者的方法
}

接下来,我们需要创建具体的元素类:

java">// 2. 创建具体元素类
// 第一个元素类
class TextElement implements DocumentElement {private String content;public TextElement(String content) {this.content = content;}@Overridepublic void accept(DocumentVisitor visitor) {visitor.visit(this); // 双分派关键点}public String getContent() { return content; }
}
java">// 第二个元素类
class ImageElement implements DocumentElement {private String src;public ImageElement(String src) {this.src = src;}@Overridepublic void accept(DocumentVisitor visitor) {visitor.visit(this);}public String getSrc() { return src; }
}

接着,我们要定义访问者接口,即该访问者能够干的事情:

java">// 3. 定义访问者接口
interface DocumentVisitor {void visit(TextElement text);  // 重载方法处理不同元素void visit(ImageElement image);
}

然后,我们来实现具体的访问者:

java">// 4. 实现具体访问者
class HTMLExportVisitor implements DocumentVisitor {@Overridepublic void visit(TextElement text) {System.out.println("<p>" + text.getContent() + "</p>");}@Overridepublic void visit(ImageElement image) {System.out.println("<img src=\"" + image.getSrc() + "\"/>");}
}
java">class MarkdownExportVisitor implements DocumentVisitor {@Overridepublic void visit(TextElement text) {System.out.println(text.getContent() + "\n");}@Overridepublic void visit(ImageElement image) {System.out.println("![](" + image.getSrc() + ")");}
}

紧接着,我们要定义一个能够持有被访问元素的数据结构

java">// 5. 对象结构(管理元素集合)
class Document {private List<DocumentElement> elements = new ArrayList<>();public void addElement(DocumentElement e) {elements.add(e);}public void accept(DocumentVisitor visitor) {for (DocumentElement e : elements) {e.accept(visitor); // 触发访问操作}}
}

最后,测试下上述代码,看看客户端的执行效果:

java">// 客户端使用
public class VisitorDemo {public static void main(String[] args) {Document doc = new Document();doc.addElement(new TextElement("Hello Visitor Pattern"));doc.addElement(new ImageElement("diagram.jpg"));// 不同访问者实现不同处理doc.accept(new HTMLExportVisitor());doc.accept(new MarkdownExportVisitor());}
}

由此可见,访问者模式的核心思想是为了访问比较复杂的数据结构,不改变数据结构。而是把对数据的访问方式抽象出来,在访问数据的过程中以回调形式在访问者中处理操作逻辑。

如果要新增一组操作,只需要新增一个访问者。

总结

访问者模式是为了抽象出一组作用于复杂对象的操作,并且后续可以新增操作而不需要对现有的数据结构做出改动。


http://www.ppmy.cn/server/178548.html

相关文章

爬虫案例-爬取某狗音乐

文章目录 1、爬取代码2、效果图 1、爬取代码 import time import requests import hashlib import jsonpath import osurl "https://wwwapi.kugou.com/play/songinfo"#伪造请求头 header {"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)…

openvela新时代的国产开源RTOS系统

openvela 简介 openvela 操作系统专为 AIoT 领域量身定制&#xff0c;以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势&#xff0c;已成为众多物联网设备和 AI 硬件的技术首选&#xff0c;涵盖了智能手表、运动手环、智能音箱、耳机、智能家…

Linux安装go环境

安装一个lazydocker&#xff0c;根据文档需要先安装go环境 https://github.com/jesseduffield/lazydocker 官方文档解析 https://go.dev/doc/install 文档内容如下&#xff0c;一共三步 1.删除先前安装的go&#xff0c;解压下载的go压缩包到/usr/local目录 2.添加环境变量&…

java设计模式之建造者模式《装修启示录》​

周五的早上&#xff0c;项目经理小白还沉浸在即将到达的假期的喜悦中&#xff0c;喝着9块9的瑞幸咖啡畅想人生时&#xff0c;老板突然拍出一张装修设计图&#xff1a;"小~白~啊&#xff08;此处请脑补领导拉长音&#xff09;&#xff0c;新办公室装修就交给你了&#xff0…

[GHCTF 2025]Popppppp[pop链构造] [php原生类的利用] [双md5加密绕过]

题目 <?php error_reporting(0);class CherryBlossom {public $fruit1;public $fruit2;public function __construct($a) {$this->fruit1 $a;}function __destruct() {echo $this->fruit1;}public function __toString() {$newFunc $this->fruit2;return $new…

使用hel-micro微服务实现在jsp项目中引入react组件

以下是一个完整的示例&#xff0c;涵盖 React子应用配置、JSP主应用集成 以及 样式隔离 的实现细节。我们将通过 CSS Modules 和 Shadow DOM 确保React样式与JSP样式互不干扰。 一、React子应用配置 1. 项目结构 react-module/ ├── src/ │ ├── index.js # 模块…

LeetCode面试经典150题

目录 力扣80. 删除有序数组中的重复项 II 代码解析 力扣274. H 指数 代码解析 力扣151. 反转字符串中的单词 解析代码 力扣12. 整数转罗马数字 解析代码 力扣28. 找出字符串中第一个匹配项的下标 解析代码1&#xff08;暴力模拟&#xff09; 解析代码2&#xff08;K…

JVM的组成--运行时数据区

JVM的组成 1、类加载器&#xff08;ClassLoader&#xff09; 类加载器负责将字节码文件从文件系统中加载到JVM中&#xff0c;分为&#xff1a;加载、链接&#xff08;验证、准备、解析&#xff09;、和初始化三个阶段 2、运行时数据区 运行时数据区包括&#xff1a;程序计数…