Java设计模式之访问者模式

embedded/2025/3/28 16:05:18/

概念

访问者模式是一种行为设计模式,允许在不修改已有代码的情况下,动态地添加新的操作到对象结构中。它将数据结构与操作解耦,使得可以独立地定义作用于复杂对象结构的操作。

作用

访问者模式的主要作用是解决在一个对象结构上定义多个操作的问题,特别是这些操作需要频繁改变时。它使得可以在不修改对象结构的前提下,方便地添加新的操作,符合单一职责原则和开闭原则。

使用场景

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

2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类。

3.对象结构中的对象类型很少改变,但经常需要在此对象结构上定义新的操作。

实现

访问者模式的实现通常包括以下几个部分:

1.Visitor(访问者接口):声明了访问者可以访问哪些元素,通过为每种元素类声明一个访问操作(visit())来实现。

2.ConcreteVisitor(具体访问者):实现了Visitor接口中的访问操作,定义了对元素的具体访问行为。

3.Element(元素接口):声明了一个accept()方法,用于接受访问者访问。

4.ConcreteElement(具体元素):实现了Element接口中的accept()方法,通常会调用访问者的相应访问方法。

5.ObjectStructure(对象结构):是一个包含元素的容器,提供了遍历元素的方法,让访问者可以访问所有元素。

示例

1.访问者接口


// 访问者接口
interface ComputerPartVisitor {void visit(Mouse mouse);void visit(Keyboard keyboard);void visit(Display display);void visit(Computer computer);
}

2.具体访问者-清洁访问者

// 具体访问者 - 清洁访问者
class CleanVisitor implements ComputerPartVisitor {@Overridepublic void visit(Mouse mouse) {System.out.println("清洁鼠标");}@Overridepublic void visit(Keyboard keyboard) {System.out.println("清洁键盘");}@Overridepublic void visit(Display display) {System.out.println("清洁显示器");}@Overridepublic void visit(Computer computer) {System.out.println("清洁电脑");}
}

3.具体访问者-升级访问者

// 具体访问者 - 升级访问者
class UpgradeVisitor implements ComputerPartVisitor {@Overridepublic void visit(Mouse mouse) {System.out.println("升级鼠标驱动");}@Overridepublic void visit(Keyboard keyboard) {System.out.println("升级键盘驱动");}@Overridepublic void visit(Display display) {System.out.println("升级显示器驱动");}@Overridepublic void visit(Computer computer) {System.out.println("升级电脑系统");}
}

4.元素接口

// 元素接口
interface ComputerPart {void accept(ComputerPartVisitor visitor);
}

5.具体元素

// 具体元素 - 鼠标
class Mouse implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor visitor) {visitor.visit(this);}
}
// 具体元素 - 键盘
class Keyboard implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor visitor) {visitor.visit(this);}
}
// 具体元素 - 显示器
class Monitor implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor visitor) {visitor.visit(this);}
}
// 具体元素 - 电脑
class Computer implements ComputerPart {private List<ComputerPart> parts;public Computer() {parts = new ArrayList<>();parts.add(new Mouse());parts.add(new Keyboard());parts.add(new Monitor());}@Overridepublic void accept(ComputerPartVisitor visitor) {for (ComputerPart part : parts) {part.accept(visitor);}visitor.visit(this);}
}

6.测试类

// 使用示例
public class VisitorPatternDemo {public static void main(String[] args) {Computer computer = new Computer();ComputerPartVisitor cleanVisitor = new CleanVisitor();computer.accept(cleanVisitor);ComputerPartVisitor upgradeVisitor = new UpgradeVisitor();computer.accept(upgradeVisitor);}
}

优缺点

优点

1.单一职责原则:将相关的行为集中在一个访问者类中,而不是分散在许多被访问的类中。

2.开闭原则:在不修改已有代码的情况下,可以方便地添加新的访问者类,从而定义新的操作。

3.复用性:访问者可以复用元素类中的方法,而不需要重新实现这些方法。

缺点

1.类的依赖性:访问者和元素之间存在强依赖关系,如果元素类的接口发生改变,那么访问者类也需要相应地进行修改。

2.破坏封装性:访问者模式要求元素类暴露其内部细节,这可能会破坏元素类的封装性。

3.适用性有限:如果对象结构中的元素类型经常变化,那么使用访问者模式会增加系统的维护成本。

不使用访问者模式的实现

如果不使用访问者模式,可以通过在元素类中直接添加操作方法来实现类似的效果。例如,在上面的例子中,可以在Mouse、Keyboard、Monitor和Computer类中分别添加清洁和升级的方法。但是,这种方式会导致每个元素类都包含大量的操作方法,违反了单一职责原则,并且在需要添加新的操作时,需要修改所有元素类的代码,不符合开闭原则。

1.具体元素

// 鼠标
class Mouse {public void clean() {System.out.println("清洁鼠标");}public void upgrade() {System.out.println("升级鼠标驱动");}
}
// 键盘
class Keyboard {public void clean() {System.out.println("清洁键盘");}public void upgrade() {System.out.println("升级键盘驱动");}
}
// 显示器
class Monitor {public void clean() {System.out.println("清洁显示器");}public void upgrade() {System.out.println("升级显示器驱动");}
}
class Computer {private List<ComputerPart> parts;public Computer() {parts = new ArrayList<>();parts.add(new Mouse());parts.add(new Keyboard());parts.add(new Monitor());}public void clean() {System.out.println("清洁电脑");for (ComputerPart part : parts) {part.clean();}}public void upgrade() {System.out.println("升级电脑系统");for (ComputerPart part : parts) {part.upgrade();}}
}

2.测试类

// 使用示例
public class NoVisitorPatternDemo {public static void main(String[] args) {Computer computer = new Computer();computer.check();computer.clean();computer.upgrade();}
}

http://www.ppmy.cn/embedded/176589.html

相关文章

HandyJSON原理

HandyJSON 的优势 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式, 应用广泛. 在 App 的使用过程中, 服务端给移动端发送的大部分都是 JSON 数据, 移动端需要解析数据才能做进一步的处理. 在解析JSON数据这一块, 目前 Swift 中流行的框架基本上是 SwiftyJSON, …

MinIO搭建部署

1、命令行安装 访问monio官网下载应用程序 # wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20250228095516.0.0-1.x86_64.rpm -O minio.rpm # sudo dnf install minio.rpm # mkdir ~/minio # minio server ~/minio --console-address :90012、dock…

MySQL原理:逻辑架构

目的&#xff1a;了解 SQL执行流程 以及 MySQL 内部架构&#xff0c;每个零件具体负责做什么 理解整体架构分别有什么模块每个模块具体做什么 目录 1 服务器处理客户端请求 1.1 MySQL 服务器端逻辑架构说明 2 Connectors 3 第一层&#xff1a;连接层 3.1 数据库连接池(Conn…

基于深度学习的自动驾驶目标检测系统

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…

webpack等构建工具如何支持移除未使用的代码

Webpack 等构建工具通过 Tree Shaking&#xff08;摇树优化&#xff09;和 Dead Code Elimination&#xff08;无用代码消除&#xff09;技术来移除未使用的代码。以下是具体实现原理、配置方法及最佳实践&#xff1a; 一、Tree Shaking 的原理 Tree Shaking 是一种基于 ES Mo…

基于python+django的旅游信息网站-旅游景点门票管理系统源码+运行步骤

该系统是基于pythondjango开发的旅游景点门票管理系统。是给师弟做的课程作业。大家学习过程中&#xff0c;遇到问题可以在github咨询作者。学习过程问题可以留言哦 演示地址 前台地址&#xff1a; http://travel.gitapp.cn 后台地址&#xff1a; http://travel.gitapp.cn/ad…

K8S学习之基础四十一:Prometheus基于Pushgateway采集数据

Prometheus基于Pushgateway采集数据 ​ 拉取pushgageway镜像&#xff0c;启动容器 docker pull pushgateway docker run -d --name pushgateway -p 9091:9091 prom/pushgateway​ 浏览器查看9091端口 ​ 修改prometheus-alertmanager-cfg.yaml文件&#xff0c;在k8s-master…

【从零实现Json-Rpc框架】- 入门准备篇

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…