设计模式之~访问者模式

news2024/11/24 15:35:33

简述:

        访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

        访问者模式(Vistor Pattern)是一种将数据结构与数据操作分离的的设计模式。

结构图:

实例:

示例代码:

Visitor类:为该对象结构中ConcreteElement的每一个类声明一个Visit操作。

public abstract class Visitor {
    public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
    public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}

ConcreteVisitor:

ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。

public class ConcreteVisitor1 extends Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(String.format("%s被%s访问",concreteElementA.getClass().getSimpleName(),this.getClass().getSimpleName()));
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(String.format("%s被%s访问",concreteElementB.getClass().getSimpleName(),this.getClass().getSimpleName()));
    }

}
public class ConcreteVisitor2 extends Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(String.format("%s被%s访问",concreteElementA.getClass().getSimpleName(),this.getClass().getSimpleName()));
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(String.format("%s被%s访问",concreteElementB.getClass().getSimpleName(),this.getClass().getSimpleName()));
    }

}

Element类:定义一个accept操作,它以一个访问者为参数。

public abstract class Element {
    public abstract void accept(Visitor visitor);
}

ConcreteElement:具体元素,实现Accept操作。

public class ConcreteElementA extends Element {
    @Override
    public void accept(Visitor visitor) {
        // 充分利用双分派技术,实现处理与数据结构的分离
        visitor.visitConcreteElementA(this);
    }
    // 其他的相关方法
    public void operationA() {

    }

}
public class ConcreteElementB extends Element {
    @Override
    public void accept(Visitor visitor) {
        // 充分利用双分派技术,实现处理与数据结构的分离
        visitor.visitConcreteElementB(this);
    }

    // 其他的相关方法
    public void operationB() {

    }
}

ObjectStructure类:能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。

public class ObjectStructure {
    private List<Element> elements = new ArrayList<Element>();

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

    public void detach(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new ConcreteElementA());
        objectStructure.attach(new ConcreteElementB());

        ConcreteVisitor1 concreteVisitor1 = new ConcreteVisitor1();
        ConcreteVisitor2 concreteVisitor2 = new ConcreteVisitor2();

        objectStructure.accept(concreteVisitor1);
        objectStructure.accept(concreteVisitor2);
    }
}

优点:

  • 符合单一职责原则

  • 访问者角色非常易于扩展。(访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。)

  • 解耦了数据结构和数据操作,使得操作集合可以独立变化

缺点:

  • 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的

  • 具体元素变更比较困难

  • 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

适用场景:

  • 访问者模式适用于数据结构相对稳定的系统。它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。

  • 需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景。

  • 访问者模式的目的就是要把处理从数据结构中分离出来。很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。反之,如果这样的系统的数据结构对象易于变化,经常要有新的数据对象增加进来,就不适合使用访问者模式。

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

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

相关文章

Linux系统下C语言的编程技巧

Linux系统能够为人们提供更加安全实用的效果,保证计算机系统能够稳定的运行。利用Linux系统下首先要进行C语言的编程,掌握编程的技巧能够更好的发挥计算机的作用。如何掌握Linux系统下计算机C语言的编程技巧是计算机发展的关键要素。本文对Linux系统下计算机C语言的编程技巧进行…

【复习笔记】FreeRTOS(三)任务挂起和恢复

本文是FreeRTOS复习笔记的第三节&#xff0c;任务挂起和恢复&#xff0c;使用的开发板是stm32f407VET6&#xff0c;创建两个任务&#xff0c;task1负责闪烁LED&#xff0c;task2负责按键控制&#xff0c;当按键按下时控制任务挂起&#xff0c;按键再次按下恢复任务&#xff0c;…

【数据结构】经典排序法

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb; 直接插入排序&#x1f449;&#x1f3fb; 选择排序&…

微信支付(小程序)-java

微信支付开发者文档微信支付是腾讯公司的支付业务品牌&#xff0c;微信支付提供公众号支付、APP支付、扫码支付、刷卡支付等支付方式。微信支付结合微信公众账号&#xff0c;全面打通O2O生活消费领域&#xff0c;提供专业的互联网行业解决方案&#xff0c;微信支付支持微信红包…

访问github网络问题解决

查看wsl可用镜像列表时产生如下访问github的网络问题 C:\Users\jiangcheng> wsl --list --online 无法从“https://raw.githubusercontent.com/microsoft/WSL/master/distributions/DistributionInfo.json”中提取列表分发。无法与服务器建立连接 Error code: Wsl/WININET_…

hive任务reduce步骤卡在99%原因及解决

我们在写sql的时候经常发现读取数据不多&#xff0c;但是代码运行时间异常长的情况&#xff0c;这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀&#xff0c;大量的数据集中到了一台或者几台机器上计算&#xff0c;这些数据的计算速度远远低于平均…

Vulkan Tutorial 9 模型加载Mipmaps

目录 28 加载模型 Sample mesh 加载顶点和索引 ​编辑 顶点去重 28 加载模型 我们将使用tinyobjloader库来从OBJ文件中加载顶点和面。它的速度很快&#xff0c;而且很容易集成&#xff0c;因为它是一个像stb_image一样的单文件库。将包含tiny_obj_loader.h的目录添加到Add…

ChatGPT国内镜像站

免费国内镜像推荐&#xff08;超稳定&#xff09; 下面为大家收集了目前国内最稳定流畅的ChatGPT镜像网站 目录 机器人 博弈ai 泰cool辣 道合顺 二狗问答 核桃 WOChat GPT中文站 TomChat 利用ChatGPTMindShow三分钟生成PPT ChatGPT国内镜像是啥 ChatGPT 镜像是指…

Xpdf 阅读器源码编译后查看文件中文乱码问题解决

经查阅&#xff0c;是由于缺少中文字体包&#xff1a; 第一步&#xff1a;下载所需要的字体包 下载https://dl.xpdfreader.com/xpdf-t1fonts.tar.gz 包含下载中文字体包&#xff08;非嵌入字体&#xff09; http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/gkai00mp…

pytorch-简单回归问题-手写数字识别

pytorch-简单回归问题-手写数字识别 线性回归添加噪声简单例子分类问题引入-手写数字识别数据集 训练推导手写数字识别1加载数据集编写网络训练网络计算正确率 线性回归添加噪声 使用均方差损失函数来衡量损失 简单例子 通过最小化损失函数&#xff0c;求解出参数w b 下图表示…

封装的函数停发/启动CAN报文,以及报文接收检测,高可用

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 📘前言 🍅 在测试过程中,我们可能需要可控的停/发某些报文,今天博主给…

chatgpt赋能python:Python主页面的SEO分析及优化建议

Python主页面的SEO分析及优化建议 Python是一种高级编程语言&#xff0c;广泛应用于人工智能、数据分析、Web开发等领域。Python官方网站是Python社区的一个重要门户&#xff0c;为全球学习Python的开发者提供了全面、权威、可靠的信息。在这篇文章中&#xff0c;我们将分析Py…

Text to image论文精读SeedSelect: 使用SeedSelect微调扩散模型It’s all about where you start

随着文本到图像扩散模型的发展&#xff0c;很多模型已经可以合成各种新的概念和场景。然而&#xff0c;它们仍然难以生成结构化、不常见的概念、组合图像。今年4月巴伊兰大学和OriginAI发表《It’s all about where you start: Text-to-image generation with seed selection》…

软件外包开发项目原型图工具

项目原型图工具有非常重要的作用&#xff0c;尤其是在APP项目开发中&#xff0c;对于整体需求的表达是必不可少的工具。相比于传统的文档需求&#xff0c;图形文字的表达可以更清楚的表达需求&#xff0c;让客户清楚的明白软件功能有哪些&#xff0c;最后的界面是怎样的&#x…

微信海量数据查询如何从1000ms降到100ms?

&#x1f449;腾小云导读 微信的多维指标监控平台&#xff0c;具备自定义维度、指标的监控能力&#xff0c;主要服务于用户自定义监控。作为框架级监控的补充&#xff0c;它承载着聚合前 45亿/min、4万亿/天的数据量。当前&#xff0c;针对数据层的查询请求也达到了峰值 40万/m…

RL - 强化学习 上置信界算法 (UCB) 和 汤普森采样算法 (TS)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/130983835 上置信界算法和汤普森采样算法是两种解决多臂老虎机问题的经典方法。多臂老虎机问题是一种探索与利用的平衡问题&#xff0c;…

Java easypoi 导出excel 并合并相关列

在项目开发中经常会使用到合并列&#xff0c;格式如下&#xff1a; 1.引入easypoi <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId></dependency><dependency><groupId>cn.aftertur…

设计模式详解之策略模式

作者&#xff1a;刘文慧 策略模式是一种应用广泛的行为型模式&#xff0c;核心思想是对算法进行封装&#xff0c;委派给不同对象来管理&#xff0c;本文将着眼于策略模式进行分享。 一、概述 我们在进行软件开发时要想实现可维护、可扩展&#xff0c;就需要尽量复用代码&#x…

chatgpt赋能python:Python什么情况下用类

Python什么情况下用类 在Python编程中&#xff0c;类是一种重要的数据结构&#xff0c;它是面向对象编程的核心。类可定义数据类型&#xff0c;并把数据与操作数据的函数组合在一起。因此&#xff0c;通过使用类&#xff0c;我们可以将数据、函数和其他方法组合在一起&#xf…

OLAP系列:四、clickhouse分布式表使用指南

一、背景 ClickHouse中最强大的表引擎当属MergeTree&#xff08;合并树&#xff09;引擎及该系列&#xff08;*MergeTree&#xff09;中的其他引擎&#xff0c;支持索引和分区&#xff0c;地位可以相当于innodb之于Mysql。 而且基于MergeTree&#xff0c;还衍生出了很多小弟&a…