设计模式中,访问者(Visitor)设计模式的概念、作用、示例代码和总结,一文详解。

访问者(Visitor)设计模式详解

一、概念解释

访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

一句话总结:访问者模式的目的是 将数据结构与对数据的操作分离,允许在不修改数据结构的情况下,新增新的操作。


二、访问者模式的作用

  • 解耦:将对象结构和操作逻辑分离。
  • 扩展性强:新增操作时无需修改原有结构,只需要添加新的访问者类。
  • 适用场景:复杂数据结构(如树、文件系统、XML)需要多种操作时。

三、示例代码

1. 定义访问者接口

public interface Visitor {
    // 访问文件夹:
    void visitDir(File dir);
    // 访问文件:
    void visitFile(File file);
}

2. 定义数据结构 FileStructure

import java.io.File;

public class FileStructure {
    // 根目录:
    private File path;

    public FileStructure(File path) {
        this.path = path;
    }

    public void handle(Visitor visitor) {
        scan(this.path, visitor);
    }

    private void scan(File file, Visitor visitor) {
        if (file.isDirectory()) {
            // 让访问者处理文件夹:
            visitor.visitDir(file);
            for (File sub : file.listFiles()) {
                // 递归处理子文件夹:
                scan(sub, visitor);
            }
        } else if (file.isFile()) {
            // 让访问者处理文件:
            visitor.visitFile(file);
        }
    }
}

3. 定义具体访问者(查找 .java 文件)

import java.io.File;

public class JavaFileVisitor implements Visitor {
    public void visitDir(File dir) {
        System.out.println("Visit dir: " + dir);
    }

    public void visitFile(File file) {
        if (file.getName().endsWith(".java")) {
            System.out.println("Found java file: " + file);
        }
    }
}

4. 定义另一个访问者(清理 .class 文件)

import java.io.File;

public class ClassFileCleanerVisitor implements Visitor {
    public void visitDir(File dir) {
        // 对文件夹不做处理
    }

    public void visitFile(File file) {
        if (file.getName().endsWith(".class")) {
            System.out.println("Will clean class file: " + file);
        }
    }
}

5. 使用访问者

import java.io.File;

public class Main {
    public static void main(String[] args) {
        FileStructure fs = new FileStructure(new File("."));

        // 查找所有 .java 文件
        fs.handle(new JavaFileVisitor());

        // 清理所有 .class 文件
        fs.handle(new ClassFileCleanerVisitor());
    }
}

四、练习题

练习:使用访问者模式递归遍历文件夹,打印所有文件的完整路径。

示例答案

import java.io.File;

// 访问者接口
interface Visitor {
    void visitDir(File dir);
    void visitFile(File file);
}

// 文件结构
class FileStructure {
    private File path;

    public FileStructure(File path) {
        this.path = path;
    }

    public void handle(Visitor visitor) {
        scan(this.path, visitor);
    }

    private void scan(File file, Visitor visitor) {
        if (file.isDirectory()) {
            visitor.visitDir(file);
            for (File sub : file.listFiles()) {
                scan(sub, visitor);
            }
        } else if (file.isFile()) {
            visitor.visitFile(file);
        }
    }
}

// 自定义访问者:打印所有文件路径
class PrintAllFilesVisitor implements Visitor {
    public void visitDir(File dir) {
        System.out.println("Directory: " + dir.getAbsolutePath());
    }

    public void visitFile(File file) {
        System.out.println("File: " + file.getAbsolutePath());
    }
}

// 测试
public class Main {
    public static void main(String[] args) {
        FileStructure fs = new FileStructure(new File("."));
        fs.handle(new PrintAllFilesVisitor());
    }
}

五、总结

  • 访问者模式核心:将数据结构操作分离。
  • 如果需要对同一数据结构增加新的操作,只需新建访问者类。
  • Java 中 Files.walkFileTree() 就是典型的访问者模式应用。
posted @ 2025-09-09 19:34  AlphaGeek  阅读(23)  评论(0)    收藏  举报