0%

visitor

Visitor


定义

表示一个作用于某对象结构中的各元素的操作

可以在不改变各元素的类的前提下定义作用于这些元素的新操作

栗子

递归遍历某个文件夹下的所有文件夹和文件

1
2
3
4
5
6
7
8
9
10
11
package eternal.fire;

import java.io.File;

public interface Visitor {
//visit a directory
void visitDir(File dir);

//visit a file
void visitFile(File file);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package eternal.fire;

import java.io.File;
import java.util.Objects;

public class FileStructure {
private File path;

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

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

private void scan(File file, Visitor visitor) {
if (file.isDirectory()) {
visitor.visitDir(file);
for (File f : Objects.requireNonNull(file.listFiles())) {
scan(f, visitor);
}
} else if (file.isFile()) {
visitor.visitFile(file);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package eternal.fire;

import java.io.File;

public class JavaFileVisitor implements Visitor {

@Override
public void visitDir(File dir) {
System.out.println("I'm visiting the directory:" + dir);
}

@Override
public void visitFile(File file) {
System.out.println("I'm visiting the file:" + file);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package eternal.fire;

import java.io.File;

public class ClassFileVisitor implements Visitor{

@Override
public void visitDir(File dir) {

}

@Override
public void visitFile(File file) {
if (file.getName().endsWith(".class")) {
System.out.println("I'm visiting the class file");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
package eternal.fire;

import java.io.File;

public class Main {
public static void main(String[] args) {
FileStructure fileStructure = new FileStructure(new File("."));
fileStructure.handle(new JavaFileVisitor());
fileStructure.handle(new ClassFileVisitor());
}
}

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
I'm visiting the directory:.
I'm visiting the directory:.\.idea
I'm visiting the file:.\.idea\.gitignore
I'm visiting the file:.\.idea\misc.xml
I'm visiting the file:.\.idea\modules.xml
I'm visiting the file:.\.idea\workspace.xml
I'm visiting the directory:.\out
I'm visiting the directory:.\out\production
I'm visiting the directory:.\out\production\Visitor
I'm visiting the directory:.\out\production\Visitor\eternal
I'm visiting the directory:.\out\production\Visitor\eternal\fire
I'm visiting the file:.\out\production\Visitor\eternal\fire\ClassFileVisitor.class
I'm visiting the file:.\out\production\Visitor\eternal\fire\FileStructure.class
I'm visiting the file:.\out\production\Visitor\eternal\fire\JavaFileVisitor.class
I'm visiting the file:.\out\production\Visitor\eternal\fire\Main.class
I'm visiting the file:.\out\production\Visitor\eternal\fire\Visitor.class
I'm visiting the directory:.\src
I'm visiting the directory:.\src\eternal
I'm visiting the directory:.\src\eternal\fire
I'm visiting the file:.\src\eternal\fire\ClassFileVisitor.java
I'm visiting the file:.\src\eternal\fire\FileStructure.java
I'm visiting the file:.\src\eternal\fire\JavaFileVisitor.java
I'm visiting the file:.\src\eternal\fire\Main.java
I'm visiting the file:.\src\eternal\fire\Visitor.java
I'm visiting the file:.\Visitor.iml
I'm visiting the class file:.\out\production\Visitor\eternal\fire\ClassFileVisitor.class
I'm visiting the class file:.\out\production\Visitor\eternal\fire\FileStructure.class
I'm visiting the class file:.\out\production\Visitor\eternal\fire\JavaFileVisitor.class
I'm visiting the class file:.\out\production\Visitor\eternal\fire\Main.class
I'm visiting the class file:.\out\production\Visitor\eternal\fire\Visitor.class

Process finished with exit code 0

优势

新增操作而不必对现有的对象结构做任何改动