设计模式-行为型模式-访问者模式
访问者模式难以实现,且应用该模式可能会导致代码可读性变差,可维护性变差,除非必要,不建议使用;
1.访问者模式定义
允许在运行时将一个或多个操作应用于一组对象,将操作与对象结构分离;
访问者模式主要解决的是数据与算法的耦合问题,尤其是在数据结构比较稳定,而算法多变的情况下,为了不污染数据本身,访问者会将多种算法独立归档,并在访问数据时根据数据类型自动切换到对应的算法,实现数据的自动响应机制,并确保算法的自由扩展;
1.1 访问者模式优缺点
优点
- 扩展性好,在不修改对象结构中元素的情况下,为对象结构中的元素添加新的功能;
- 复用性好,通过访问者来定义整个对象结构通用的功能,从而提高复用程度;
- 分离无关行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一;
缺点
- 对象结构变化很困难,在访问者模式中,没增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了开闭原则;
- 违反了依赖倒置原则,访问者模式依赖了具体类,而没有依赖抽象类;
1.2 访问者模式的使用场景
- 当对象的数据结构相对稳定,而操作却经常变化的时候。 比如,上面例子中路由器本身的内部构造(也就是数据结构)不会怎么变化,但是在不同操作系统下的操作可能会经常变化,比如,发送数据、接收数据等。
- 需要将数据结构与不常用的操作进行分离的时候。 比如,扫描文件内容这个动作通常不是文件常用的操作,但是对于文件夹和文件来说,和数据结构本身没有太大关系(树形结构的遍历操作),扫描是一个额外的动作,如果给每个文件都添加一个扫描操作会太过于重复,这时采用访问者模式是非常合适的,能够很好分离文件自身的遍历操作和外部的扫描操作。
- 需要在运行时动态决定使用哪些对象和方法的时候。 比如,对于监控系统来说,很多时候需要监控运行时的程序状态,但大多数时候又无法预知对象编译时的状态和参数,这时使用访问者模式就可以动态增加监控行为。
2.访问者模式原理
- 抽象访问者(Visitor):可以是接口或抽象类,定义了一系列操作方法,用来处理所有数据元素,通常为同名的访问方法,并以数据元素作为入参来确定哪个重载方法被调用;
- 具体访问者(ConcreteVisitor):实现了抽象访问者,可以有多个,每个访问者都需要实现所有数据元素类型的访问重载发方法;
- 抽象元素类(Element):被访问的数据元素接口,定义了一个接受访问者的方法,每个元素都要可以被访问者访问;
- 具体元素类(ConcreteElement):具体数据元素实现类,提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法;
- 对象结构类(ObjectStructure):包含所有可能被访问的数据对象的容器,可以提供数据对象的迭代功能,可以是任意类型的数据结构;
- 客户端:使用容器并初始化其中各类数据元素,并选择合适的访问者处理容器中的所有数据对象;
3.访问者模式的实现
【实例】
以超市购物为例,假设超市中的两类商品:糖果、酒水进行售卖。我们可以忽略每种商品的计价方法,因为最终结账时由收银员统一集中处理,在商品类中添加计价方法是不合理的设计;
【代码】
访问者接口
public interface Visitor {public void visit(Wine wine); //酒类重载方法public void visit(Candy candy); //糖果重载方法
}
接待者接口
public interface Acceptable {//接收所有的Visitor访问者的子类实现类public void accept(Visitor visitor);
}
糖果类(酒类类似)
public class Candy extends Product implements Acceptable{public Candy(String name, LocalDate producedDate, double price) {super(name, producedDate, price);}@Overridepublic void accept(Visitor visitor) {//accept实现方法中调用访问者并将自己 "this" 传回。this是一个明确的身份,不存在任何泛型visitor.visit(this);}
}
具体访问者——折扣计价访问者
public class DiscountVisitor implements Visitor {private LocalDate billDate;public DiscountVisitor(LocalDate billDate) {this.billDate = billDate;System.out.println("结算日期: " + billDate);}@Overridepublic void visit(Candy candy) {System.out.println("糖果: " + candy.getName());//获取产品生产天数long days = billDate.toEpochDay() - candy.getProducedDate().toEpochDay();if(days > 180){System.out.println("超过半年的糖果,请勿食用!");}else{double rate = 0.9;double discountPrice = candy.getPrice() * rate;System.out.println("糖果打折后的价格"+NumberFormat.getCurrencyInstance().format(discountPrice));}}@Overridepublic void visit(Wine wine) {System.out.println("酒类: " + wine.getName()+",无折扣价格!");System.out.println("原价: "+NumberFormat.getCurrencyInstance().format(wine.getPrice()));}
}
客户端
public class Client {public static void main(String[] args) {//模拟添加多个商品的操作List<Acceptable> products = Arrays.asList(new Candy("金丝猴奶糖",LocalDate.of(2022,6,10),10.00),new Wine("衡水老白干",LocalDate.of(2020,6,10),100.00));Visitor visitor = new DiscountVisitor(LocalDate.of(2022,10,17));for (Acceptable product : products) {product.accept(visitor);}}
}
相关文章:

设计模式-行为型模式-访问者模式
访问者模式难以实现,且应用该模式可能会导致代码可读性变差,可维护性变差,除非必要,不建议使用; 1.访问者模式定义 允许在运行时将一个或多个操作应用于一组对象,将操作与对象结构分离; 访问者…...
探索Oracle数据库的多租户特性:架构、优势与实践
在云计算和大数据时代,多租户架构成为数据库设计中的一个重要趋势。Oracle数据库的多租户选项(Multitenant)允许单个数据库实例支持多个独立数据库(称为容器数据库和可插拔数据库),每个数据库都有自己的数据…...

Hack The Box-Sightless
总体思路 CVE-2022-0944->密码破解->chrome调试->PHP-FPM命令执行 信息收集&端口利用 nmap -sSVC sightless.htbStarting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-11 08:40 CST Nmap scan report for sightless.htb Host is up (0.84s latency). Not sh…...
Linux驱动开发-字符设备驱动开发
linux 驱动开发1. 驱动程序的类型2. 驱动开发流程字符设备驱动 1. 基本概念2. 字符设备驱动的基本结构 架构字符设备驱动开发中常用的 API示例以下代码加入了设备类和设备实例的创建 linux 驱动开发 1. 驱动程序的类型 在 Linux 中,驱动程序主要有以下几种类型&am…...

好用的电脑录屏软件有哪些?推荐4款专业工具。
不同系统的电脑上面带有的录屏功能不一样,比如win10上面有Xbox game bar,Mac系统则用的是QuickTime Player,或者是使用快捷键“CommandShift5”。但更方便的,我自己认为是使用一些专业的录屏软件,他门的录制模式多,兼容…...

web基础之XSS
一、搭建XSS平台 安装 1、我这里安装在本地的Phpstudy上,安装过程就是一路下一步(可以改安装路径),附上下载链接: # 官网:https://www.xp.cn/download.html# 蓝莲花 - github下载 https://github.com/fi…...
目标检测-小目标检测方法
小目标检测是计算机视觉中的一个挑战性问题,因为小目标往往在图像中占据的像素较少,容易被背景或其他物体干扰。为了有效地进行小目标检测,研究人员和工程师提出了多种方法和算法来提高检测精度。以下是一些针对小目标检测的有效方式和算法&a…...

连接数据库(以MySQL为例)
文章目录 前言一、数据库是什么?二、连接步骤 1.手动导入驱动包2.连接数据库总结 前言 面对应用程序的开发,普遍需要保存用户的海量数据。保存粮的库叫粮库,保存水的库叫水库,那么保存数据的库自然叫数据库。有了数据库࿰…...

Mysql高级教程
1.安装部署 安装依赖性: [rootmysql-node10 ~]# dnf install cmake gcc-c openssl-devel ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el7_4.x86_64.rpm rpcgen.x86_64 下载并解压源码包 [rootmysql-node10 ~]# tar zxf mysql-boost-5.7.44.tar.gz [rootmysql-no…...

基于Ubuntu2404搭建mysql8配置远程访问
使用系统为Ubuntu2404,mysql8版本为8.0.36 安装mysql apt install -y mysql-server设置开机自启动 systemctl enable --now mysql修改密码,似乎是bug,修改密码第一次不成功,第二次可以 mysql use mysql; update user set Host…...
前端工程师职业发展路线图
在前端开发领域,从一个新手成长为一名资深工程师需要经过一系列的学习和实践。以下是一份详细的前端工程师职业发展路线图,包括了从基础到高级的各个阶段。 入门阶段 1. 学习基础技术 HTML/HTML5:掌握网页结构和语义化标签的使用。CSS/CSS…...

人工智能(AI)正在以前所未有的速度融入我们生活的方方面面
人工智能将融入我们生活的方方面面 人工智能(AI)正在以前所未有的速度融入我们生活的方方面面,这种趋势在未来几年乃至几十年内将会持续加速。以下是一些人工智能已经或即将在各个领域产生深远影响的例子: 智能家居:…...
OpenCV-模板匹配多个目标
文章目录 一、基本概念二、基本步骤1.图像准备2.图像预处理3.执行模板匹配4.定位匹配区域5.处理多个匹配6.优化和验证 三、代码实现1.图片读取2.图像预处理3.模板匹配4.绘制矩形框 三、总结 模型匹配(Model Matching)是一个广泛应用的概念,其…...

uniapp 原生插件开发 UI
前言: 在集成某些特定 原生SDK的时候,它本身是带UI控件的。当我们使用 uniapp 开发app的时候实是 可以使使用 nvue 页面,以 weex 的方式嵌入原生的UI控件。 我这边的场景是 接入连连app的支付,它有个自己的密码键盘 控件是原生的页…...

性能测试-性能分析与调优原理总结
性能分析与调优如何下手,先从硬件开始,还是先从代码或数据库。 从操作系统(CPU调度,内存管理,进程调度,磁盘I/O)、网络、协议(HTTP, TCP/IP ),还是…...
【机器学习】4 ——熵
机器学习4 ——熵 文章目录 机器学习4 ——熵前言 前言 熵衡量随机变量不确定性,由克劳德香农(Claude Shannon)在1948年提出,称为香农熵。反映了一个系统中信息的混乱程度或信息量。 其定义为: H ( P ) − ∑ x P …...

linux命令用于删除文本文件中的重复行的命令uniq详解
目录 一、概述 二、基本用法 1、uniq 命令的基本语法 2、常用选项 3、获取帮助 三、主要功能 1. 识别并删除相邻重复行 2. 保留重复行的第一个实例 3. 统计重复次数 4. 忽略指定列的比较 四、示例 1. 删除相邻重复行 2. 显示每一行及其重复次数 3. 只显示重复行 4. …...

PHP智驭未来悦享生活智慧小区物业管理小程序系统源码
智驭未来,悦享生活 —— 探索智慧小区物业管理小程序 一、引言:智慧生活的新篇章 在这个日新月异的时代,科技正以前所未有的速度改变着我们的生活。从智能家居到智慧城市,每一处都闪耀着智慧的光芒。而今天,我要带大家…...
深度学习:怎么看pth文件的参数
.pth 文件是 PyTorch 模型的权重文件,它通常包含了训练好的模型的参数。要查看或使用这个文件,你可以按照以下步骤操作: 1. 确保你有模型的定义 你需要有创建这个 .pth 文件时所用的模型的代码。这意味着你需要有模型的类定义和架构。 2. …...

MMLU-Pro 基准测试数据集上线,含 12k 个跨学科复杂问题,难度提升,更具挑战性!DeepSeek 数学模型一键部署
在大语言模型 (LLM) 蓬勃发展的时代,诸如大规模多任务语言理解 (MMLU) 之类的基准测试,在推动 AI 于不同领域的语言理解与推理能力迈向极限方面,发挥着至关重要的关键作用。 然而,伴随模型的持续改进与优化,LLM 在这些…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...