行为模式11.访问者模式

news2025/1/12 15:20:00

行为型模式

  1. 模板方法模式(Template Method Pattern)
  2. 命令模式(Command Pattern)
  3. 迭代器模式(Iterator Pattern)
  4. 观察者模式(Observer Pattern)
  5. 中介者模式(Mediator Pattern)
  6. 备忘录模式(Memento Pattern)
  7. 解释器模式(Interpreter Pattern)
  8. 状态模式(State Pattern)
  9. 策略模式(Strategy Pattern)
  10. 职责链模式(Chain of Responsibility Pattern)
  11. 访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不改变元素类的前提下,定义作用于这些元素的操作。它通过将操作封装到访问者对象中,使得可以在不修改元素对象的情况下,增加新的操作。

访问者模式的主要组成部分:

  1. 元素接口(Element):定义接受访问者的方法。
  2. 具体元素(ConcreteElement):实现元素接口,并实现接受访问者的方法。
  3. 访问者接口(Visitor):定义对每个具体元素的访问方法。
  4. 具体访问者(ConcreteVisitor):实现访问者接口,对每个具体元素进行操作。
  5. 对象结构(ObjectStructure):管理元素对象的集合,它可以通过接受访问者来触发访问操作。

访问者模式的优点:

  • 增加新操作:可以在不改变元素类的情况下,增加新的操作。每增加一个新的操作,就只需要添加一个新的访问者。
  • 解耦操作和数据结构:访问者模式将操作从数据结构中提取出来,操作逻辑集中在访问者中,元素类仅负责存储数据和提供访问接口。

访问者模式的缺点:

  • 增加了系统的复杂度:需要定义多个访问者类和元素类,代码结构可能变得更加复杂。
  • 不易于修改元素类:如果元素类频繁修改,可能会导致访问者类的修改也变得复杂。

示例:访问者模式的 Java 实现

1. 定义元素接口(Element)
interface Element {
    void accept(Visitor visitor);
}
2. 定义具体元素(ConcreteElement)
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationA() {
        System.out.println("具体元素A的操作A");
    }
}

class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationB() {
        System.out.println("具体元素B的操作B");
    }
}
3. 定义访问者接口(Visitor)
interface Visitor {
    void visit(ConcreteElementA elementA);
    void visit(ConcreteElementB elementB);
}
4. 定义具体访问者(ConcreteVisitor)
class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ConcreteElementA elementA) {
        System.out.println("具体访问者正在访问具体元素A");
        elementA.operationA();
    }

    @Override
    public void visit(ConcreteElementB elementB) {
        System.out.println("具体访问者正在访问具体元素B");
        elementB.operationB();
    }
}
5. 定义对象结构(ObjectStructure)
class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}
6. 客户端代码(Client)
public class Client {
    public static void main(String[] args) {
        // 创建元素对象
        Element elementA = new ConcreteElementA();
        Element elementB = new ConcreteElementB();

        // 创建对象结构,并将元素添加到结构中
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.addElement(elementA);
        objectStructure.addElement(elementB);

        // 创建访问者
        Visitor visitor = new ConcreteVisitor();

        // 让对象结构接受访问者
        objectStructure.accept(visitor);
    }
}

8. 总结

  • 元素类(ConcreteElementA、ConcreteElementB):实现了 Element 接口,表示可以被访问的元素,且定义了具体的操作方法。
  • 访问者接口(Visitor):定义了访问每个元素的方法。
  • 具体访问者(ConcreteVisitor):实现了对每个具体元素的操作。
  • 对象结构(ObjectStructure):包含了多个元素对象,负责将访问者传递给每个元素对象。

访问者模式的关键思想是将数据结构和操作分离,使得在不修改数据结构的情况下可以增加新的操作,适用于那些数据结构经常变化,但操作比较固定的场景。

适用场景:

  • 需要在不改变对象结构的情况下,增加新的操作时。
  • 对象结构中的对象不常变化,但需要对其执行不同的操作时。

    文中的示例代码在我的码云:https://gitee.com/ming-super/design-model.git

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

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

相关文章

spring boot解决swagger中的v2/api-docs泄露漏洞

在配置文件中添加以下配置 #解决/v2/api-docs泄露漏洞 springfox:documentation:swagger-ui:enabled: falseauto-startup: false 处理前&#xff1a; 处理后&#xff1a;

【Linux】深入理解文件系统(超详细)

目录 一.磁盘 1-1 磁盘、服务器、机柜、机房 &#x1f4cc;补充&#xff1a; &#x1f4cc;通常网络中用高低电平&#xff0c;磁盘中用磁化方向来表示。以下是具体说明&#xff1a; &#x1f4cc;如果有一块磁盘要进行销毁该怎么办&#xff1f; 1-2 磁盘存储结构 ​编辑…

CSS如何让一个盒子或内容在指定区域中上下左右居中

要使用CSS让盒子或内容在其父元素中上下左右居中&#xff0c;可以使用多种方法。例如&#xff1a;flexbox布局、使用grid布局、box布局、使用position定位和transform结合、以及表格属性等等&#xff0c;相关属性来实现内容的上下左右的居中。 接下来我们使用以上的方法&#x…

用户注册模块用户校验(头条项目-05)

1 用户注册后端逻辑 1.1 接收参数 username request.POST.get(username) password request.POST.get(password) phone request.POST.get(phone) 1.2 校验参数 前端校验过的后端也要校验&#xff0c;后端的校验和前端的校验是⼀致的 # 判断参数是否⻬全 # 判断⽤户名是否…

Qt学习笔记第81到90讲

第81讲 串口调试助手实现自动发送 为这个名叫“定时发送”的QCheckBox编写槽函数。 想要做出定时发送的效果&#xff0c;必须引入QT框架下的毫秒级定时器QTimer&#xff0c;查阅手册了解详情。 在widget.h内添加新的私有成员变量&#xff1a; QTimer *timer; 在widget类的构造…

hutool-http实现离线爬虫

文章目录 1.数据爬取流程2.离线爬虫(Hutool-http实现)1.获取数据2.数据清洗3.为什么有各种类型的强转4.数据入库 3.测试完整代码 1.数据爬取流程 1.分析数据源(怎么获取) 2.拿到数据后怎么处理 3.写入数据库存储 2.离线爬虫(Hutool-http实现) 1.获取数据 这里返回的是jso…

【C语言】_使用冒泡排序模拟实现qsort函数

目录 1. 排序函数的参数 2. 排序函数函数体 2.1 比较元素的表示 2.2 交换函数Swap的实现 2.3 排序函数bubble_sort的实现 3. 测试整型数据排序 3.1 整型数据比较函数cmp_int的实现 3.2 整型数据排序后输出函数print_int的实现 3.3 整型数据测试函数test_int的实现 3…

ECharts饼图下钻

背景 项目上需要对Echarts饼图进行功能定制&#xff0c;实现点击颜色块&#xff0c;下钻显示下一层级占比 说明 饼图实现点击下钻/面包屑返回的功能 实现 数据结构 [{name: a,value: 1,children: [...]},... ]点击下钻 // 为图表绑定点击事件&#xff08;需要在destroy…

Java聊天小程序

拟设计一个基于 Java 技术的局域网在线聊天系统,实现客户端与服务器之间的实时通信。系统分为客户端和服务器端两类,客户端用于发送和接收消息,服务器端负责接收客户端请求并处理消息。客户端通过图形界面提供用户友好的操作界面,服务器端监听多个客户端的连接并管理消息通…

蓝桥杯嵌入式速通(1)

1.工程准备 创建一文件夹存放自己的代码&#xff0c;并在mdk中include上文件夹地址 把所有自身代码的头文件都放在headfile头文件中&#xff0c;之后只需要在新的文件中引用headfile即可 headfile中先提前可加入 #include "stdio.h" #include "string.h"…

net-http-transport 引发的句柄数(协程)泄漏问题

Reference 关于 Golang 中 http.Response.Body 未读取导致连接复用问题的一点研究https://manishrjain.com/must-close-golang-http-responsehttps://www.reddit.com/r/golang/comments/13fphyz/til_go_response_body_must_be_closed_even_if_you/?rdt35002https://medium.co…

TrustRAG:增强RAG系统鲁棒性与可信度的创新框架

在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;LLMs&#xff09;凭借其强大的语言处理能力在诸多领域大放异彩。检索增强生成&#xff08;RAG&#xff09;系统&#xff08;面向企业RAG&#xff08;Retrieval Augmented Generation&#xff09;系统的多维检索框架…

业务链指标,用户行为模式识别,埋点系统

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 此前&#xff0c;我们已经成功搭建起最为基础的聚类指标体系&#xff0c;涵盖计数、求和、最大值、最小…

Git撤销指定commit并更新远端仓库

Git撤销指定commit并更新远端仓库 一、撤销指定commit 1.首先执行git log 命令&#xff0c;查看git历史提交以及commit信息&#xff1a; 由于需要脱敏&#xff0c;所以截图可能看得马赛克比较多&#xff0c;需要关注的就是上面的commit后跟的id&#xff0c;以及HEAD当前指定…

基于DFT与IIR-FIR滤波器的音频分析与噪声处理

基于DFT与IIR-FIR滤波器的音频分析与噪声处理 【完整源码文档报告】 【需要可随时联系博主&#xff0c;常在线能秒回!】 系统功能与实现介绍 功能与实现 音频处理系统界面搭建&#xff1a;利用MATLAB的GUI工具&#xff0c;构建了音频分析界面&#xff0c;包括文件导入、录…

基于单片机的无线气象仪系统设计(论文+源码)

1系统方案设计 如图2.1所示为无线气象仪系统设计框架。系统设计采用STM32单片机作为主控制器&#xff0c;结合DHT11温湿度传感器、光敏传感器、BMP180气压传感器、PR-3000-FS-N01风速传感器实现气象环境的温度、湿度、光照、气压、风速等环境数据的检测&#xff0c;并通过OLED1…

MySQL库表的操作

目录 一、库的操作 1.1库的创建 1.2字符集和校验规则 1.2.1 查看系统默认字符集以及校验规则 1.2.2 查看数据库支持的字符集 1.2.3 查看数据库支持的字符集校验规则 1.2.4 校验规则对数据库的影响 1.3操纵数据库 1.3.1显示库 1.3.2显示创建语句 1.3.3修改数据库 1.3…

硬件设计-齐纳管

目录 摘要 详情 齐纳管的工作电流、 摘要 齐纳管&#xff08;Zener Diode&#xff09;是一种特殊的二极管&#xff0c;它能够在特定的反向电压下保持电流稳定。正常情况下&#xff0c;二极管只允许正向电流通过&#xff0c;而阻止反向电流流过。而齐纳管在一定的反向电压下可…

Airflow:TimeSensor感知时间条件

在数据管道工作流中&#xff0c;任务可能需要在特定的时间执行&#xff0c;或者在继续之前等待一定的时间。为了满足这些需求&#xff0c;Apache Airflow提供了TimeSensor&#xff0c;这是一种内置Sensor&#xff0c;可以监控当前时间&#xff0c;并在达到指定时间时触发后续任…

libusb学习——简单介绍

文章目录 libusb 简介libusb 编译libusb 源码目录介绍核心代码文件平台支持例子 API使用libusb初始化和去初始化libusb设备处理和枚举libusb 杂项libusb USB描述符libusb 设备热插拔事件通知libusb 异步设备I/Olibusb 同步设备I/Olibusb 轮询与定时 libusb 涉及技术参考 libusb…