设计模式-访问者设计模式
介绍
访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变个元素的类的前提下定义作用于这些元素的新操作。
问题:在一个机构里面有两种员工,1.Teacher 2.Engineer 员工有name, income, vacationDays三种属性,想要对不同的员工有不同的算法实现更新income和vacationDays的操作。
首先引导出策略模式,对员工实现不同的算法策略实现更新操作。
基础代码
test类
package Stragy;import java.util.ArrayList;
import java.util.List;public class test {public static void main(String[] args) {Employee e1 = new Teacher("张三", 8000, 10);Employee e2 = new Engineer("李四", 7000, 20);Visitor visitor = new IncomeVisitor();List<Employee> employeeList = new ArrayList<>();employeeList.add(e1);employeeList.add(e2);for(Employee e : employeeList){visitor.visit(e);}for(Employee e : employeeList){System.out.println(e);}}
}
Employee类
package Stragy;public abstract class Employee {private String name;private double income;private int vacationDays;public Employee(String name, double income, int vacationDays) {this.name = name;this.income = income;this.vacationDays = vacationDays;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getIncome() {return income;}public void setIncome(double income) {this.income = income;}public int getVacationDays() {return vacationDays;}public void setVacationDays(int vacationDays) {this.vacationDays = vacationDays;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", income=" + income +", vacationDays=" + vacationDays +'}';}
}
Engineer类
package Stragy;public class Engineer extends Employee{public Engineer(String name, double income, int vacationDays) {super(name, income, vacationDays);}}
Teacher类
package Stragy;public class Teacher extends Employee {public Teacher(String name, double income, int vacationDays) {super(name, income, vacationDays);}
}
Visitor类
package Stragy;public abstract class Visitor {public abstract void visit(Employee e);
}
IncomeVisitor类
package Stragy;public class IncomeVisitor extends Visitor{@Overridepublic void visit(Employee e) {if(e instanceof Teacher){e.setIncome(e.getIncome() + 500);}if(e instanceof Engineer){e.setIncome(e.getIncome() + 800);}}
}
VacationDaysVisitor类
package Stragy;public class VacationDayVisitor extends Visitor{@Overridepublic void visit(Employee e) {e.setVacationDays(e.getVacationDays() + 8);}
}
策略模式
基础代码就是按照策略模式实现的,但是在不同的员工对算法的不同选择上尚可优化,在策略模式中,是通过 if 语句判断算法的不同选择。
package Stragy;public class IncomeVisitor extends Visitor{@Overridepublic void visit(Employee e) {if(e instanceof Teacher){e.setIncome(e.getIncome() + 500);}if(e instanceof Engineer){e.setIncome(e.getIncome() + 800);}}
}
在IncomeVisitor类中,通过instanceof判断当前员工是哪种类型来选择实现哪种算法,使用访问者的双分派方式可以省去 if 语句,也就是使用两次动态绑定。
访问者模式
在访问者模式中,修改了以下内容:
在Employee类中添加accept抽象方法
public abstract void accept(Visitor visitor);
在Engineer类中重写
@Overridepublic void accept(Visitor visitor) {visitor.EngineerVisit(this);}
在Teacher类中重写
@Overridepublic void accept(Visitor visitor) {visitor.TeacherVisit(this);}
在Visitor类中不再使用visit方法,替换为不同员工的算法选择,在此处,我的理解是用两个不同的方法代替了 if 语句。
package visitor;public abstract class Visitor {public abstract void TeacherVisit(Employee e);public abstract void EngineerVisit(Employee e);
}
在VacationDaysVisitor中重写
package visitor;public class VacationDaysVisitor extends Visitor{@Overridepublic void TeacherVisit(Employee e) {e.setVacationDays(e.getVacationDays() + 5);}@Overridepublic void EngineerVisit(Employee e) {e.setVacationDays(e.getVacationDays() + 8);}
}
在IncomeVisitor中重写
package visitor;public class IncomeVisitor extends Visitor{@Overridepublic void TeacherVisit(Employee e) {e.setIncome(e.getIncome() + 500);}@Overridepublic void EngineerVisit(Employee e) {e.setIncome(e.getIncome() + 800);}
}
测试类中修改调用方式
package visitor;import java.util.ArrayList;
import java.util.List;public class test {public static void main(String[] args) {Employee e1 = new Teacher("张三", 8000, 10);Employee e2 = new Engineer("李四", 7000, 20);Visitor visitor = new IncomeVisitor();VacationDaysVisitor vacationDaysVisitor = new VacationDaysVisitor();List<Employee> employeeList = new ArrayList<>();employeeList.add(e1);employeeList.add(e2);for(Employee e : employeeList){e.accept(visitor);e.accept(vacationDaysVisitor);}for(Employee e : employeeList){System.out.println(e);}}
}
在测试类中
for(Employee e : employeeList){e.accept(visitor);e.accept(vacationDaysVisitor);}
此处调用accept方法进行更新的时候,使用到双分派的技术在选择 e 员工的时候用到一次动态绑定,绑定到真实的员工,在 Engineer和Teacher中选择 visitor 算法的时候再次用到动态绑定,绑定到真实的IncomeVisitor或VacationDaysVisitor,通过两次绑定,即可为合适的员工选择合适的算法。
@Overridepublic void accept(Visitor visitor) {visitor.EngineerVisit(this);}
运行结果如下

如有错误,敬请指正
相关文章:
设计模式-访问者设计模式
介绍 访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变个元素的类的前提下定义作用于这些元素的新操作。 问题:在一个机构里面有两种员工,1.Teacher 2.Engineer 员…...
Spring框架IOC
目录 一、Spring框架的介绍 1.1 Spring框架的概述 1.2 Spring框架的优点 二、Spring的核心 IOC技术 2.1 什么是IOC 2.2 IOC的程序入门 2.3 IOC技术总结 2.4 Spring框架的Bean管理的配置文件方式 一、Spring框架的介绍 1.1 Spring框架的概述 Spring是一个开放源代码的…...
有哪些免费的 ERP 软件可供选择?哪些 ERP 软件使用体验较好?
想找个 “免费” 的 ERP 软件? 咱得知道,ERP 那可是涉及财务、人力、供应链、采购、销售等好多方面的重要企业软件。功能这么全,能免费才怪呢!真要是有免费的,早就火遍大江南北,说不定把市场都垄断了&…...
思科CCNA认证都学什么考什么?
关注 工 仲 好:IT运维大本营CCNA考试要学的东西很多,你不要看它只是一个初级认证,但是它的专业内容知识是不少的,你想要学好也是需要下一番苦功的。 那么考CCNA需要学哪些东西呢?下面我们就来了解一下吧。 01、考CCN…...
模型部署学习笔记——模型部署关键知识点总结
模型部署学习笔记——模型部署关键知识点总结 模型部署学习笔记——模型部署关键知识点总结1. CUDA中Grid和Block的定义是什么?Shared Memory的定义?Bank Conflict的定义?Stream和Event的定义?2. TensorRT的工作流程?3…...
22智能 狄克斯特拉算法复习
狄克斯特拉算法 图 根据边有无方向分为: 有向图、无向图 根据边有无权重变量分为: 有权图、无权图 根据顶点是否连通分为: 连通图和非连通图入度:表示有多少条边指向该顶点出度:表示有多少条边从该顶点指出算法步骤&a…...
首个!艾灵参编的工业边缘计算国家标准正式发布
近日,艾灵参与编制的《面向工业应用的边缘计算 应用指南》(以下简称《标准》)国家标准正式发布,将于2025年5月1日起实施。这一里程碑式的成果,不仅标志着我国在工业边缘计算技术标准化领域取得了重大突破,成…...
curl也支持断点续传
curl断点续传 访问外网资源,特别是Github上比较大的资源,例如,笔者遇到的calico发布包,经常会遇到在浏览器上下载半途中断。 那么支持断点续传的下载工具,就是应对这种情况的好帮手! 简单的断点续传工具…...
交换机链路聚合(手动负载分担模式)(eNSP)
目录 交换机SW_C配置: 交换机-PC划分vlan: 交换机-交换机端口聚合: 交换机SW_D配置: 交换机-PC划分vlan: 交换机-交换机端口聚合: 验证: 链路聚合的端口清除: 交换机端口聚合的存在意义主要有以下几点: 增加带宽 提高冗余性和可靠性 实现负载均衡 降低成本 …...
jmeter 接口性能测试 学习笔记
目录 说明工具准备工具配置jmeter 界面汉化配置汉化步骤汉化结果图 案例1:测试接口接口准备线程组添加线程组配置线程组值线程数(Number of Threads)Ramp-Up 时间(Ramp-Up Period)循环次数(Loop Count&…...
`HashMap`、`Hashtable` 和 `HashSet`的区别
HashMap、Hashtable 和 HashSet 都是 Java 中常用的集合类,它们的功能和实现有所不同,尽管它们都使用哈希表(hash table)作为底层数据结构。以下是它们之间的主要区别: 1. HashMap 和 Hashtable 的区别 特性HashMapH…...
Arduino中解析JSON数据
JSON JSON(JavaScript Object Notation,即JavaScript对象表示法)是一种广泛采用的开放标准文件格式与数据交换格式。它兼具人类可读性和机器易解析性,使得数据的编写、阅读、生成及解析都变得十分便捷。JSON的设计不依赖于特定编…...
linux----文件访问(c语言)
linux文件访问相关函数 打开文件函数 - open 函数原型:int open(const char *pathname, int flags, mode_t mode);参数说明: pathname:这是要打开的文件的路径名,可以是绝对路径或者相对路径。例如,"/home/user/…...
源码分析之Openlayers中MousePosition鼠标位置控件
概述 本文主要介绍 Openlayers 中的MousePosition鼠标位置控件,该控件会创建一个元素在页面的右上方用来实时显示鼠标光标的位置坐标。该控件在实际应用很有效,可以实时获取鼠标位置,但是一般控件元素都会自定义。 源码分析 MousePosition…...
以ATTCK为例构建网络安全知识图
ATT&CK(Adversarial Tactics, Techniques, and Common Knowledge )是一个攻击行为知识库和模型,主要应用于评估攻防能力覆盖、APT情报分析、威胁狩猎及攻击模拟等领域。本文简单介绍ATT&CK相关的背景概念,并探讨通过ATT&a…...
myexcel的使用
参考: (1)api文档:https://www.bookstack.cn/read/MyExcel-2.x/624d8ce73162300b.md (2)源代码: https://github.com/liaochong/myexcel/issues 我: (1)m…...
Unity 上好用的插件
PlayerMaker BehaviorDesigner Cinemachine Timeline Hybrid Addressable AssetBundle Blower Simple Zoom 大地图上缩放和平移使用ScrollRect的好效果实现...
Vivado - 远程调试 + 远程综合实现 + vmWare网络配置 + NFS 文件共享 + 使用 VIO 核
目录 1. 简介 2. VIO 配置 2.1 VIO IP 2.2 VIO 对比 ILA 3. VIO 示例 3.1 Led 3.1.1 工程配置 3.1.2 效果展示 3.2 Key 3.2.1 工程配置 3.2.1 效果展示 3.3 门控触发 3.3.1 工程配置 3.3.2 效果展示 4. 远程调试 4.1 配置目标主机 4.2 配置本机 4.3 vmWare 网…...
双臂机器人
目录 一、双臂机器人简介 二、双臂机器人系统的组成 三、双臂机器人面临的主要挑战 3.1 协调与协同控制问题 3.2 力控制与柔顺性问题 3.3 路径规划与轨迹优化问题 3.4 感知与环境交互 3.5 人机协作问题 3.6 能源与效率问题 3.7 稳定性与可靠性问题 四、双臂机器人…...
【Lua热更新】上篇
Lua 热更新 - 上篇 下篇链接:【Lua热更新】下篇 文章目录 Lua 热更新 - 上篇一、AssetBundle1.理论2. AB包资源加载 二、Lua 语法1. 简单数据类型2.字符串操作3.运算符4.条件分支语句5.循环语句6.函数7. table数组8.迭代器遍历9.复杂数据类型 - 表9.1字典9.2类9.3…...
告别重复造轮子:用快马AI一键生成Unity高效开发工具与通用模块
告别重复造轮子:用快马AI一键生成Unity高效开发工具与通用模块 在Unity游戏开发过程中,UI管理系统是最基础也最常被重复开发的模块之一。每次新项目都要从头搭建UI框架,不仅浪费时间,还容易引入不一致的设计模式。最近我在InsCod…...
零基础学linux:借助快马ai生成你的第一份命令手册与实战练习脚本
作为一个从图形界面转战Linux命令行的过来人,我完全理解新手面对黑底白字终端时的茫然感。最近在InsCode(快马)平台尝试用AI辅助学习时,发现它特别适合解决这个痛点——不仅能生成清晰易懂的命令手册,还能创建可交互的练习脚本,就…...
重生之我用 AI 复活了我的同事
阅读本文大概需要 2.8 分钟。在写这篇文章之前先解答上篇文章评论区反映的两个问题:第一个问题,有人读完文章说,张哥,那以后是用 AI 还是不用呢?当然要用了,而且是鼓励大家全面使用。我文章本意是 AI 发展之…...
Qwen3-14B WebUI定制教程:更换主题、添加历史记录、导出对话功能
Qwen3-14B WebUI定制教程:更换主题、添加历史记录、导出对话功能 1. 准备工作与环境检查 在开始定制Qwen3-14B的WebUI之前,我们需要确保环境已经正确配置并运行。以下是准备工作步骤: 1.1 确认镜像版本与硬件配置 首先检查您的环境是否符…...
Steane编码实战指南:用Python模拟[7,1,3]量子纠错电路(附完整代码)
Steane编码实战指南:用Python模拟[7,1,3]量子纠错电路(附完整代码) 量子计算正从实验室走向现实应用,但量子比特的脆弱性始终是横亘在实用化道路上的关键障碍。想象一下,当你精心设计的量子算法因为一个随机的相位翻转…...
企业微信自动化新解:PC端HOOK与iPad协议双轨实践
1. 企业微信自动化的业务痛点与双轨方案 最近两年服务企业客户时,最常被问到的就是:"每天要手动处理上千条客户消息,有没有更高效的解决方案?" 这让我意识到企业微信自动化已成为刚需。传统人工操作在批量消息发送、大规…...
Android 15 音频子系统(八):Audio HAL 与硬件接口——音频数据的最后一公里
引言:最后一公里的旅程 如果把 Android 音频系统比作一条物流网络,那么 AudioFlinger 是"中央分拣中心",AudioPolicy 是"路由规划师",而 Audio HAL(Hardware Abstraction Layer)就是最终把包裹送到用户手里的"快递员"。 前几篇我们聊了 …...
Gemma-3-12B-IT WebUI保姆级教程:含Supervisord进程守护与开机自启
Gemma-3-12B-IT WebUI保姆级教程:含Supervisord进程守护与开机自启 1. 前言:为什么选择Gemma-3-12B-IT? 如果你正在寻找一个性能强劲、部署友好,而且完全免费开源的大语言模型,那么Google的Gemma-3-12B-IT绝对值得你…...
告别黑盒:用Python拆解OpenBCI GUI的滤波与可视化模块(附完整代码)
从零构建Python版OpenBCI数据处理引擎:解码脑电信号处理全流程 在脑机接口开发领域,OpenBCI以其开源特性和专业级性能成为众多研究者的首选硬件平台。然而,其官方GUI虽然功能完善,却像一座封闭的城堡——我们能看到华丽的城墙&…...
OpenClaw自动化视频处理:Qwen2.5-VL-7B分析关键帧生成视频摘要
OpenClaw自动化视频处理:Qwen2.5-VL-7B分析关键帧生成视频摘要 1. 为什么需要自动化视频摘要 作为一个经常需要处理大量视频素材的自媒体创作者,我长期被一个痛点困扰:如何快速了解长视频的核心内容。传统方法要么是手动拖动进度条随机查看…...
