本文介绍: 想象你正在管理一个图书馆,书架上有各种书籍和盒子(代表文件和文件夹)。当你要统计所有书籍的数量和总体积时,你可以扮演“访问者”的角色,逐个检查每本书籍和盒子。打开盒子后,再继续检查盒子里的内容。在这个过程中,你不需要修改书本或盒子本身,而是通过定义一套针对不同对象的操作规则(访问者接口),实现了灵活的功能扩展。
访问者模式(Visitor Pattern)是一种行为型设计模式,它主要用于在不修改现有类结构的前提下向对象结构添加新的操作。访问者模式通过定义一个访问者接口,使得可以在不改变元素类的情况下,为各个元素类增加新的功能。
原理
- 元素接口(Element Interface): 定义了一个accept()方法,用于接收访问者对象的访问。
- 具体元素类(Concrete Elements): 实现了元素接口,并且每个类都可能有自己特有的业务逻辑和数据。
- 访问者接口(Visitor Interface): 定义了一系列访问元素的方法,对应不同的具体元素类型。
- 具体访问者类(Concrete Visitors): 实现了访问者接口,提供了对每个具体元素类进行特定操作的方法。
Java代码示例
// 元素接口
public interface Element {
void accept(Visitor visitor);
}
// 具体元素类 - 文件
public class File implements Element {
private String name;
public File(String name) {
this.name = name;
}
@Override
public void accept(Visitor visitor) {
visitor.visitFile(this);
}
// 获取文件名
public String getName() {
return name;
}
}
// 具体元素类 - 文件夹
public class Folder implements Element {
private List<Element> children;
public Folder() {
this.children = new ArrayList<>();
}
public void addElement(Element child) {
children.add(child);
}
@Override
public void accept(Visitor visitor) {
visitor.visitFolder(this);
for (Element child : children) {
child.accept(visitor);
}
}
// 获取子元素列表
public List<Element> getChildren() {
return children;
}
}
// 访问者接口
public interface Visitor {
void visitFile(File file);
void visitFolder(Folder folder);
}
// 具体访问者类 - 计算文件总数与大小
public class SizeCalculator implements Visitor {
private int fileCount;
private long totalSize;
public SizeCalculator() {
fileCount = 0;
totalSize = 0L;
}
@Override
public void visitFile(File file) {
fileCount++;
// 假设我们已有一个获取文件大小的方法
totalSize += getFileSize(file.getName());
}
@Override
public void visitFolder(Folder folder) {
for (Element element : folder.getChildren()) {
element.accept(this);
}
}
public int getFileCount() {
return fileCount;
}
public long getTotalSize() {
return totalSize;
}
// 示例方法,实际中需要从磁盘或数据库获取
private long getFileSize(String fileName) {
// 这里仅作演示,实际上会根据文件名获取真实大小
return 1024; // 假设每个文件大小为1KB
}
}
// 使用示例
public class Client {
public static void main(String[] args) {
Folder root = new Folder();
root.addElement(new File("file1.txt"));
root.addElement(new File("file2.txt"));
Folder subFolder = new Folder();
subFolder.addElement(new File("subFile1.txt"));
root.addElement(subFolder);
SizeCalculator calculator = new SizeCalculator();
root.accept(calculator);
System.out.println("Total files: " + calculator.getFileCount());
System.out.println("Total size: " + calculator.getTotalSize());
}
}
想象你正在管理一个图书馆,书架上有各种书籍和盒子(代表文件和文件夹)。当你要统计所有书籍的数量和总体积时,你可以扮演“访问者”的角色,逐个检查每本书籍和盒子。打开盒子后,再继续检查盒子里的内容。在这个过程中,你不需要修改书本或盒子本身,而是通过定义一套针对不同对象的操作规则(访问者接口),实现了灵活的功能扩展。
应用场景
- 文件系统遍历:定义一个访问者来统计文件夹中的文件数量、计算总大小等。
- 编译器语法分析:遍历抽象语法树(AST),对不同类型的节点执行不同的处理,如类型检查、代码生成等。
适用性
- 对象结构稳定但需要频繁增加新的操作。
- 需要对一组相似的对象结构执行不同的操作。
- 想要在不影响这些对象的情况下定义新操作。
原文地址:https://blog.csdn.net/weixin_44145894/article/details/135653778
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_59002.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。