Go和Java实现访问者模式

Go和Java实现访问者模式

我们下面通过一个解压和压缩各种类型的文件的案例来说明访问者模式的使用。

1、访问者模式

在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随

着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者

对象就可以处理元素对象上的操作。

  • 意图:主要将数据结构与数据操作分离。

  • 主要解决:稳定的数据结构和易变的操作耦合问题。

  • 何时使用:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这

    些对象的类,使用访问者模式将这些封装到类中。

  • 如何解决:在被访问的类里面加一个对外提供接待访问者的接口。

  • 关键代码:在数据基础类里面有一个方法接受访问者,将自身引用传入访问者。

  • 应用实例:您在朋友家做客,您是访问者,朋友接受您的访问,您通过朋友的描述,然后对朋友的描述做出一

    个判断,这就是访问者模式。

  • 优点:1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。

  • 缺点:1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒

    置原则,依赖了具体类,没有依赖抽象。

  • 使用场景:1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一

    个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希

    望在增加新操作时修改这些类。

  • 注意事项:访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。

  • 适用性:

    一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。

    需要对一个对象结构中的对象进行很多不同的并且不相关的操作,让你想避免让这些操作污染这些对象的类。

    Visitor使得你可以将相关的操作集中起来定义在一个类中,当该对象结构被很多应用共享时,用Visitor模

    式让每个应用仅包含需要用到的操作。

    定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者

    的接口,这可能想要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

2、Go实现访问者模式

package visitor// ========== 访问者FileUseVisitor ==========
type FileUseVisitor interface {// 为每一个类声明一个visit操作visitPdfFile(FileResourceVisitable)visitPPTFile(FileResourceVisitable)visitTextFile(FileResourceVisitable)
}
package visitorimport "fmt"// ========== 访问者Compress ==========
type Compress struct {
}func (compress *Compress) visitPdfFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Compress file: " + fileResourceVisitable.(*PdfFile).Path)
}func (compress *Compress) visitPPTFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Compress file: " + fileResourceVisitable.(*PPTFile).Path)
}func (compress *Compress) visitTextFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Compress file: " + fileResourceVisitable.(*TextFile).Path)
}
package visitorimport "fmt"// ========== 访问者Decompress ==========
type Decompress struct {
}func (decompress *Decompress) visitPdfFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Decompress file: " + fileResourceVisitable.(*PdfFile).Path)
}func (decompress *Decompress) visitPPTFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Decompress file: " + fileResourceVisitable.(*PPTFile).Path)
}func (decompress *Decompress) visitTextFile(fileResourceVisitable FileResourceVisitable) {fmt.Println("Decompress file: " + fileResourceVisitable.(*TextFile).Path)
}
package visitor// ========== 接收者FileResourceVisitable ==========
type FileResourceVisitable interface {accept(FileUseVisitor)
}
package visitor// ========== 接收者PdfFile ==========
type PdfFile struct {Path string
}func (pdfFile *PdfFile) accept(fileUseVisitor FileUseVisitor) {fileUseVisitor.visitPdfFile(pdfFile)
}
package visitor// ========== 接收者PPTFile ==========
type PPTFile struct {Path string
}func (pPTFile *PPTFile) accept(fileUseVisitor FileUseVisitor) {fileUseVisitor.visitPPTFile(pPTFile)
}
package visitor// ========== 接收者TextFile ==========
type TextFile struct {Path string
}func (textFile *TextFile) accept(fileUseVisitor FileUseVisitor) {fileUseVisitor.visitTextFile(textFile)
}
package visitor// ========== FileStructure ==========
type FileStructure struct {fileResourceVisitableList []FileResourceVisitable
}func (fileStructure *FileStructure) Attach(fileResourceVisitable FileResourceVisitable) {fileStructure.fileResourceVisitableList = append(fileStructure.fileResourceVisitableList, fileResourceVisitable)
}func (fileStructure *FileStructure) Detach(fileResourceVisitable FileResourceVisitable) {for i := 0; i < len(fileStructure.fileResourceVisitableList); i++ {if fileStructure.fileResourceVisitableList[i] == fileResourceVisitable {fileStructure.fileResourceVisitableList = append(fileStructure.fileResourceVisitableList[:i], fileStructure.fileResourceVisitableList[i+1:]...)}}
}func (fileStructure *FileStructure) Accept(fileUseVisitor FileUseVisitor) {for _, fileResourceVisitable := range fileStructure.fileResourceVisitableList {fileResourceVisitable.accept(fileUseVisitor)}
}
package mainimport . "proj/visitor"func main() {fileStructure := FileStructure{}fileStructure.Attach(&PPTFile{Path: "test.ppt"})fileStructure.Attach(&PdfFile{Path: "test.pdf"})fileStructure.Attach(&TextFile{Path: "test.txt"})fileStructure.Accept(&Decompress{})fileStructure.Accept(&Compress{})
}
# 输出
Decompress file: test.ppt
Decompress file: test.pdf
Decompress file: test.txt
Compress file: test.ppt
Compress file: test.pdf
Compress file: test.txt

3、Java实现访问者模式

package com.visitor;// ========== 访问者FileUseVisitor ==========
public interface FileUseVisitor {// 为每一个类声明一个visit操作void visitPdfFile(FileResourceVisitable fileResourceVisitable);void visitPPTFile(FileResourceVisitable fileResourceVisitable);void visitTextFile(FileResourceVisitable fileResourceVisitable);
}
package com.visitor;// ========== 访问者Compress ==========
public class Compress implements FileUseVisitor{@Overridepublic void visitPdfFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Compress file: "+fileResourceVisitable.path);}@Overridepublic void visitPPTFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Compress file: "+fileResourceVisitable.path);}@Overridepublic void visitTextFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Compress file: "+fileResourceVisitable.path);}
}
package com.visitor;// ========== 访问者Decompress ==========
public class Decompress implements FileUseVisitor{@Overridepublic void visitPdfFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Decompress file: "+fileResourceVisitable.path);}@Overridepublic void visitPPTFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Decompress file: "+fileResourceVisitable.path);}@Overridepublic void visitTextFile(FileResourceVisitable fileResourceVisitable) {System.out.println("Decompress file: "+fileResourceVisitable.path);}
}
package com.visitor;// ========== 接收者FileResourceVisitable ==========
public abstract class FileResourceVisitable {protected String path;abstract void accept(FileUseVisitor fileUseVisitor);
}
package com.visitor;// ========== 接收者PdfFile ==========
public class PdfFile extends FileResourceVisitable {public PdfFile(String path){this.path = path;}@Overridepublic void accept(FileUseVisitor fileUseVisitor) {fileUseVisitor.visitPdfFile(this);}
}
package com.visitor;// ========== 接收者PPTFile ==========
public class PPTFile extends FileResourceVisitable {public PPTFile(String path){this.path = path;}@Overridepublic void accept(FileUseVisitor fileUseVisitor) {fileUseVisitor.visitPPTFile(this);}
}
package com.visitor;// ========== 接收者TextFile ==========
public class TextFile extends FileResourceVisitable {public TextFile(String path){this.path = path;}@Overridepublic void accept(FileUseVisitor fileUseVisitor) {fileUseVisitor.visitTextFile(this);}
}
package com.visitor;import java.util.ArrayList;
import java.util.List;
import java.util.Objects;// ========== FileStructure ==========
public class FileStructure {List<FileResourceVisitable> fileResourceVisitableList = new ArrayList<>();public void attach(FileResourceVisitable fileResourceVisitable){fileResourceVisitableList.add(fileResourceVisitable);}public void detach(FileResourceVisitable fileResourceVisitable){Objects.requireNonNull(fileResourceVisitable);}public void accept(FileUseVisitor fileUseVisitor){for(FileResourceVisitable fileResourceVisitable:fileResourceVisitableList){fileResourceVisitable.accept(fileUseVisitor);}}
}
package com.visitor;public class Test {public static void main(String[] args) {FileStructure fileStructure = new FileStructure();fileStructure.attach(new PPTFile("test.pdf"));fileStructure.attach(new PdfFile("test.pdf"));fileStructure.attach(new TextFile("test.txt"));fileStructure.accept(new Compress());fileStructure.accept(new Decompress());}
}
# 输出
Compress file: test.pdf
Compress file: test.pdf
Compress file: test.txt
Decompress file: test.pdf
Decompress file: test.pdf
Decompress file: test.txt

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

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

相关文章

nginx负载均衡的几种配置方式介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备&#xff1a; 2.190均衡服务器&#xff0c;2.191web服务器1&#xff0c;2.160web服务器2&#xff0c;三台设备均安装nginx&#xff0c;两台web服务器均有网页内容 1.一般轮询负载均衡 &#xff08;1&#xff09…

9.1网络通信基础

一.基础概念: 1)IP地址:描述网络上的一个设备所在的位置. 2)端口号(port):区分一个主机上不同的进程,和pid一样的作用,但两者不同. 3)协议:网络通信传输数据的含义,协议表示一种约定,这种约定可以是任意的.协议分层之后,上层不需要知道下层协议的细节,可以灵活地调整,替换某…

JavaScript:解构赋值【对象】

在JavaScript编程中&#xff0c;解构赋值是一种强大的技术&#xff0c;它允许我们从数组或对象中快速提取数据并赋值给变量。在本文中&#xff0c;我们将重点介绍对象解构&#xff0c;解释如何利用它从对象中提取数据&#xff0c;以通俗易懂的方式帮助你掌握这一技巧。 1. 什么…

【行为型设计模式】C#设计模式之观察者模式

题目&#xff1a;假设你正在开发一个简单的新闻发布系统&#xff0c;该系统允许用户订阅不同的新闻频道&#xff0c;并在有新闻发布时向订阅者发送通知。使用观察者模式设计和实现该系统。观察者模式的相关概念和定义&#xff1a; 观察者模式是一种行为设计模式&#xff0c;它定…

Docker容器监控(Cadvisor +Prometheus+Grafana)

环境部署&#xff0c;接着上一篇文章Docker容器部署&#xff08;Cadvisor InfluxDBGrafana&#xff09;开始 目录 1、先清理一下容器 2、部署Cadvisor 3、访问Cadvisor页面 4、部署Prometheus 5、准备配置 6、运行prometheus容器 7、访问prometheus页面 8、部署Grafan…

华为od机试面试题目

1.华为机试102道题解 2.华为机考题目 2023年7月30日 19:30~22:00 机考提示&注意事项(考前必看): 1、注意编译环境的变化及语言选择&#xff0c;选自己熟悉的语言机考。 2、机考共3道题&#xff0c;150分钟完成。 3、题目难度为:一星和两星;2道一星的题目&#xff0c;各…

gin和gorm框架安装

理论上只要这两句命令 go get -u gorm.io/gorm go get -u github.com/gin-gonic/gin然而却出现了问题 貌似是代理问题&#xff0c;加上一条命令 go env -w GOPROXYhttps://goproxy.cn,direct 可以成功安装 安装gorm的数据库驱动程序 go get -u gorm.io/driver/mysql

鸿蒙边缘计算网关正式开售

IDO-IPC3528鸿蒙边缘计算网关基于RK3568研发设计&#xff0c;采用22nm先进工艺制程&#xff0c;四核A55 CPU&#xff0c;主频高达2.0GHz&#xff0c;支持高达8GB高速LPDDR4&#xff0c;1T算力NPU&#xff0c;4K H.265/H264硬解码&#xff1b;视频输出接口HDMI2.0&#xff0c;双…

大专非科班转码成功自白

大专非科班转码成功自白 文章目录 大专非科班转码成功自白初步学习进阶学习提供阶段面试阶段总结 2023年是博主从业18年以来找工作最难的一年。但程序员这个行业还是被很多毕业生青睐。就业相对比较好&#xff0c;收入相对比较高&#xff0c;虽然面临996&#xff0c;依然给很多…

vue3中使用toValue

toValue() 是一个在 3.3 版本中新增的 API。它的设计目的是将 ref 或 getter 规范化为值。如果参数是 ref&#xff0c;它会返回 ref 的值&#xff1b;如果参数是函数&#xff0c;它会调用函数并返回其返回值 示例

Linux yum 命令,Linux apt 命令

目录 Linux yum 命令 yum 语法 yum常用命令 实例 1 实例 2 实例 3 国内 yum 源

腾讯云服务器购买流程_三种方法图文指南

腾讯云服务器购买流程直接在活动上成本更低&#xff0c;在云服务器CVM或轻量应用服务器页面自定义选择比较gui&#xff0c;但是自定义云服务器CPU内存带宽配置选择范围广&#xff0c;活动上只能选择固定的活动机&#xff0c;选择范围窄&#xff0c;但是云服务器成本低。腾讯云服…

高效处理矢量大数据的高可用解决方案

高效处理矢量大数据的高可用解决方案 解决方案目标 存储海量矢量数据实时分析海量矢量数据实现海量矢量数据的可视化提供高可用、高性能和高可拓展性解决方案概述 海量数据查询与可视化 系统技术流程 方案一 数据存储: PostgreSQL+PostGIS(矢量数据存储和空间分析)数据服务…

PAT 1036 Boys vs Girls

个人学习记录&#xff0c;代码难免不尽人意。 Sample Input 1: 3 Joe M Math990112 89 Mike M CS991301 100 Mary F EE990830 95 Sample Output 1: Mary EE990830 Joe Math990112 6 Sample Input 2: 1 Jean M AA980920 60 Sample Output 2: Absent Jean AA980920 NA #include&…

MFC计算分贝

分贝的一种定义是&#xff0c;表示功率量之比的一种单位&#xff0c;等于功率强度之比的常用对数的10倍&#xff1b; 主要用于度量声音强度&#xff0c;常用dB表示&#xff1b; 其计算&#xff0c;摘录网上一段资料&#xff1b; 声音的分贝值可以通过以下公式计算&#xff1…

leetcode做题笔记66

给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个整数不会以零开头。 思路一&#xff1a;模拟题意 int* plusOne(i…

NLP 时事和见解【2023】

一、说明 AI的新闻当然不是即时的&#xff0c;但作为趋势和苗头&#xff0c;我们不得不做出自己的决定。比如&#xff0c;一些软件的支持是否持续&#xff0c;哪些现成的软件将不再使用&#xff0c;等等。 图片来自中途 以下是NLPlanet为您选择的有关NLP和AI的每周文章&#x…

Linux命令200例:tree用于以树状结构显示文件和目录

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

android:输入框时局部上移

一、我遇到的情况是登录界面&#xff0c;在我输入用户名时下面的输入框被遮挡。很影响美观&#xff0c;于是我就在看很多ap上在你输入时整个界面是不会被遮挡的&#xff0c;我看了其他博主的解决过程后我的也不存在遮挡问题了。 二、我的解决方案: 方法一&#xff1a;在你的A…

Live800:客服常用的6大提问技巧,帮助客服服务更高效

作为企业最前线的客服&#xff0c;提升服务质量是必须要做到的&#xff0c;而如何提升服务质量呢&#xff1f;其中一项关键点就是提问技巧。在客户沟通中&#xff0c;提问的方式和技巧直接影响着客户对企业服务的满意度。下面&#xff0c;本文将介绍客服常用的6大提问技巧&…