设计模式行为型——访问者模式

news2024/11/16 19:37:18

目录

访问者模式的定义

访问者模式的实现

访问者模式角色

访问者模式类图

访问者模式举例

访问者模式代码实现

访问者模式的特点

优点

缺点

使用场景

注意事项

实际应用


访问者模式的定义

        访问者模式(Visitor Pattern)属于行为型设计模式,它允许在不修改现有对象结构的前提下,定义对这些对象执行操作的新操作。访问者模式将数据结构和操作分离,使得操作可以独立变化。

        访问者模式基本思想是,针对系统中拥有固定类型数的对象结构(元素),在其内提供一个 accept()方法来接受访问者对象的访问。不同的访问者对同一个元素的访问内容是不同,使得相同的元素集合可以产生不同的数据结果。

访问者模式的实现

访问者模式角色

  1. 抽象访问者角色(Visitor):接口或者抽象类,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
  2. 具体访问者角色(ConcreteVisitor):实现Visitor声明的接口,是每个操作实现的部分。
  3. 抽象元素角色(Element):接口或者抽象类,该类定义了一个接受访问者访问的方法 accept()方法,表示所有元素类型都支持被访问者访问。
  4. 具体元素角色(ConcreteElement):具体元素类型,实现了抽象元素(Element)所定义的接受操作接口。
  5. 结构对象角色(ObjectStructure):该类内部维护了元素集合,并提供方法接受访问者对该集合所有元素进行操作。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

访问者模式类图

访问者模式举例

访问者模式代码实现

抽象访问者角色

package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 抽象访问者角色 
 * @date 2023/08/09 21:48:44
 */
public interface ComputerPartVisitor {

    void visit(ComputerHost computerHost);

    void visit(Mouse mouse);

    void visit(Keyboard keyboard);

    void visit(Monitor monitor);
}

具体访问者角色

package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 实体访问者角色 计算机部件显示访问者
 * @date 2023/08/09 21:54:19
 */
public class ComputerPartDisplayVisitor implements ComputerPartVisitor{
    @Override
    public void visit(ComputerHost computerHost) {
        System.out.println("Displaying Computer.");
    }

    @Override
    public void visit(Mouse mouse) {
        System.out.println("Displaying Mouse.");
    }

    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Displaying Keyboard.");
    }

    @Override
    public void visit(Monitor monitor) {
        System.out.println("Displaying Monitor.");
    }
}

抽象元素角色

package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 抽象元素角色 计算机组成部分
 * @date 2023/08/09 21:47:18
 */
public interface ComputerPart {
    void accept(ComputerPartVisitor computerPartVisitor);
}

具体元素角色

package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体元素角色 电脑主机
 * @date 2023/08/09 21:50:15
 */
public class ComputerHost implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}
package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体元素角色 键盘
 * @date 2023/08/09 21:50:15
 */
public class Keyboard implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}
package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体元素角色 显示器
 * @date 2023/08/09 21:50:15
 */
public class Monitor implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}
package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体元素角色 鼠标
 * @date 2023/08/09 21:50:15
 */
public class Mouse implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}

结构对象角色

package com.common.demo.pattern.visitor;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 结构对象角色 电脑
 * @date 2023/08/09 21:50:15
 */
public class Computer{

    private List<ComputerPart> employeeList = new ArrayList<>();

    {
        employeeList.add(new ComputerHost());
        employeeList.add(new Keyboard());
        employeeList.add(new Monitor());
        employeeList.add(new Mouse());
    }

    //遍历
    public void showReport(ComputerPartVisitor visitor){
        for (ComputerPart computerPart : this.employeeList) {
            computerPart.accept(visitor);
        }
    }
}



测试代码

package com.common.demo.pattern.visitor;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 测试代码
 * @date 2023/08/09 22:00:44
 */
public class Test {
    public static void main(String[] args) {

        Computer computer = new Computer();
        computer.showReport(new ComputerPartDisplayVisitor());
    }

}

测试截图

访问者模式的特点

优点

  1. 增加新的操作更容易:通过访问者模式,可以在不修改现有对象结构的情况下增加新的操作,符合开闭原则。
  2. 将相关操作集中到一个访问者类中:访问者模式将相关操作封装在一个访问者类中,使得代码更加结构化和清晰。
  3. 扩展性强:由于访问者模式将数据结构和操作解耦,因此可以方便地添加新的数据结构和操作,扩展性强。
  4. 解耦性:解耦了数据结构与数据操作,使得操作集合可以独立变化。

缺点

  1. 增加新的元素类困难:当需要增加新的元素类时,需要同时修改访问者接口和所有的具体访问者类,可能导致修改的范围较大。
  2. 违反了单一职责原则:访问者模式将相关操作集中到访问者类中,可能导致该类承担过多的责任,违反单一职责原则。
  3. 违背依赖倒置原则:访问者角色依赖的是具体元素类型,而不是抽象。

使用场景

  1. 当需要对一组对象执行多种不同且不相关的操作时,可以考虑使用访问者模式。
  2. 数据结构稳定,数据结构与数据操作分离,作用于数据结构的操作经常变化的场景。

注意事项

  1. 对象结构稳定:在使用访问者模式时,对象结构应该是相对稳定的,避免频繁修改对象结构,否则会导致访问者接口和具体访问者类的修改范围较大。
  2. 具体元素类的扩展:如果需要频繁添加新的元素类,可能会增加访问者接口和具体访问者类的修改工作量,需要谨慎设计。

实际应用

  1. 编译器的语法树分析:编译器可以使用访问者模式来遍历语法树,对不同类型的节点执行不同的操作。
  2. 数据结构的序列化:对于复杂的数据结构,可以使用访问者模式来实现序列化操作,将对象转换为特定格式的字符串或字节流。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

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

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

相关文章

总结950

7:00起床 7:30~8:00复习单词300个&#xff0c;记忆100个 8:10~9:30数学660&#xff0c;只做了10道题&#xff0c;发现对各知识点的掌握程度不一。有些熟练&#xff0c;有些生疏 9:33~10:25计算机网络课程1h 10:32~12:02继续660&#xff0c;也不知道做了几道 2:32~4:00数据…

Node.js |(四)HTTP协议 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;HTTP概念&#x1f4da;窥探HTTP报文&#x1f4da;请求报文的组成&#x1f407;HTTP请求行&#x1f407;HTTP请求头&#x1f407;HTTP的请求体 &#x1f4da;响应报文…

阔别三年,领先回归!别克LPGA锦标赛申城十月再启高球盛会

2023年8月4日——2023年金秋十月&#xff0c;阔别中国赛场已久的别克LPGA锦标赛将强势归来&#xff0c;于10月12日至15日在上海旗忠花园高尔夫俱乐部再次拉开帷幕。作为三年来首个回归、同时也是今年国内唯一开赛的国际顶级高尔夫职业赛事&#xff0c;别克LPGA锦标赛将吸引全世…

零代码集成融云连接更多应用

融云是安全、可靠的全球互联网通信云服务商&#xff0c;向开发者和企业提供即时通讯和实时音视频通信云服务。 场景描述&#xff1a; 基于融云的开放api能力&#xff0c;无代码集成融云平台的音视频通话、即时通信、聊天室、短信等业务&#xff0c;使融云连通其它应用。通过A…

Mirror网络库 | 说明

此篇为上文&#xff0c;下篇&#xff1a;Mirror网络库 | 实战 一、介绍 基于UNET&#xff0c;从2014年经过9年实战测试&#xff1b;服务器和客户端是一个项目&#xff1b;使用NetworkBehaviour而不是MonoBehaviour&#xff0c;还有NetworkServer和NetworkClient&#xff1b;Mi…

nodejs安装ffi报错,windows-build-tools安装不成功

首先要确定nodejs的版本 要使用v17.x.x版本的nodejs Index of /dist/latest-v17.x/&#xff0c;才能安装windows-build-tools npm install --global --production windows-build-tools 执行命令 他会去下载很多编译需要用的文件。一方面是python27&#xff0c;另一方面是B…

双周赛110(模拟、枚举+哈希表)

文章目录 双周赛110[2806. 取整购买后的账户余额](https://leetcode.cn/problems/account-balance-after-rounded-purchase/)模拟 [2807. 在链表中插入最大公约数](https://leetcode.cn/problems/insert-greatest-common-divisors-in-linked-list/)模拟 [2808. 使循环数组所有元…

Linux 终端操作命令(2)内部命令分类

Linux 终端操作命令 也称Shell命令&#xff0c;是用户与操作系统内核进行交互的命令解释器&#xff0c;它接收用户输入的命令并将其传递给操作系统进行执行&#xff0c;可分为内部命令和外部命令。内部命令是Shell程序的一部分&#xff0c;而外部命令是独立于Shell的可执行程序…

06-4_Qt 5.9 C++开发指南_MDI应用程序设计

文章目录 1. MDI简介2. 文档窗口类 QFormDoc 的设计3. MDI主窗口设计与子窗口的使用3.1 主窗口界面设计3.2 MDI子窗口的创建与加入3.3 QMdiArea 常用功能函数3.4 MDI的信号 4. 源码4.1 qwmainwindow.h4.2 qwmainwindow.cpp 1. MDI简介 传统的应用程序设计中有多文档界面(Multi…

canal 嵌入式部署 监听binlog

canal 嵌入式部署 背景技术选型canal原理用途嵌入式代码实现引入pom引入工具pommain方法引入常量定义install方法buildCanal方法pull方法printSummaryprintEntry2 总结谢谢 背景 最近发现一个需求,需要监听mysql 数据库里的数据变动, 但由于架构方面的原因, 只能做成单体嵌入式…

7.4 并行连接网路GoogLeNet

由来&#xff1a;吸收了NiN网络的串联网络思想&#xff0c;并在此基础上做了改进 解决的问题&#xff1a;什么样大小的卷积核最合适的问题。使用不同大小的卷积核组合是有利的。 GoogLeNet架构 GoogLeNet的Inception块的架构 上图中的复杂小块的具体内容如下&#xff1a; i…

导出LLaMA ChatGlm2等LLM模型为onnx

通过onnx模型可以在支持onnx推理的推理引擎上进行推理&#xff0c;从而可以将LLM部署在更加广泛的平台上面。此外还可以具有避免pytorch依赖&#xff0c;获得更好的性能等优势。 这篇博客&#xff08;大模型LLaMa及周边项目&#xff08;二&#xff09; - 知乎&#xff09;进行…

解决监督学习,深度学习报错:AttributeError: ‘xxx‘ object has no attribute ‘module‘!!!!

哈喽小伙伴们大家好呀&#xff0c;很长时间没有更新啦&#xff0c;最近在研究一个问题&#xff0c;就是AttributeError: xxx object has no attribute module 今天终于是解决了&#xff0c;所以来记录分享一下&#xff1a; 我这里出现的问题是&#xff1a; 因为我的数据比较大…

QColorDialog

QColorDialog 颜色类 QColor颜色对话框API简单的使用 QColorDialog类是QDialog的子类, 通过这个类我们可以得到一个选择颜色的对话框窗口 颜色类 QColor 关于颜色的属性信息, 在QT框架中被封装到了一个叫QColor的类中。 各种颜色都是基于红, 绿, 蓝这三种颜色调配而成的, 并…

大模型开发工程师的成长路径(此篇文章持续更新)

导言&#xff1a;现在大模型如日中天&#xff0c;引起广大技术圈的强烈关注&#xff0c;现在投身于大模型开发&#xff0c;就是第一批的大模型开发工程师&#xff0c;必然能享受到行业内的先行者优势和红利。 我就是个俗人&#xff0c;工资待遇这么高&#xff0c;肯定要转行啊…

研发工程师玩转Kubernetes——PVC使用Label和storage选择PV

在《研发工程师玩转Kubernetes——local型PV和PVC绑定过程中的状态变化》和《研发工程师玩转Kubernetes——使用local型PV在不同Pod上共享数据》中&#xff0c;我们介绍了指定VPC的spec.volumeName为PV名称来绑定它们的方法。本文将介绍PVC在创建时&#xff0c;系统自动选择绑定…

SpringBoot 简单入门部署

1. 环境要求 Java 8 (配置环境变量)Maven 3.3idea 2019.1.2 及以上 1.1 maven 配置 <mirrors><mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/n…

中国IT统一运维ITSM软件市场,云智慧再次稳居榜首!

日前&#xff0c;国际数据公司IDC发布《2022年中国IT统一运维软件市场总结》报告&#xff0c;报告显示&#xff0c;云智慧2022年全年继续保持ITSM市场第一。 图1&#xff1a;2022年中国IT统一运维ITSM软件市场&#xff0c;云智慧再次夺冠 根据IDC数据显示&#xff0c;2022年中…

重发布选路最佳实验

题目 IP地址配置 R1&#xff1a; R2&#xff1a; R3&#xff1a; R4&#xff1a; 双点重发布 R2&#xff1a; rip 1 version 2 network 12.0.0.0 network 2.0.0.0 import-route ospf 1 ospf 1 import-route rip 1 route-policy R2 area 0.0.0.0 network 23.1.1.0 0.0…

实现链式队列

dl.h dl.c main.c 结果