什么是访问者模式
访问者模式(Visitor)是一种操作一组对象的操作,它的目的是不改变对象的定义,但允许新增不同的访问者,来定义新的操作。
核心:数据结构与处理分离开来
例子
文件与文件夹处理
文件结构
定义文件处理,使用递归的方式
package BehavioralPattern.VisitorMode;
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);
}
}
}
访问者接口
package BehavioralPattern.VisitorMode;
import java.io.File;
/**
* 访问者
*/
public interface Visitor {
void visitDir(File dir);
void visitFile(File file);
}
java文件访问者
package BehavioralPattern.VisitorMode;
import java.io.File;
/**
* java文件访问者
*/
public class JavaFileVisitor implements Visitor{
@Override
public void visitDir(File dir) {
System.out.println("Visit dir: " + dir);
}
@Override
public void visitFile(File file) {
if(file.getName().endsWith(".java")){
System.out.println("Found java file: " + file);
}
}
}
class文件访问者
package BehavioralPattern.VisitorMode;
import java.io.File;
/**
* class文件访问者
*/
public class ClassFileVisitor implements Visitor{
@Override
public void visitDir(File dir) {
System.out.println("Visit dir: " + dir);
}
@Override
public void visitFile(File file) {
if(file.getName().endsWith(".java")){
System.out.println("Found class file: " + file);
}
}
}
Main
package BehavioralPattern.VisitorMode;
import java.io.File;
/**
* Main
*/
public class Main {
public static void main(String[] args) {
FileStructure fs = new FileStructure(new File("D:\\demo\\hello-security"));
fs.handle(new JavaFileVisitor());
fs.handle(new ClassFileVisitor());
}
}
结果
ps:这个路径下没有.class结尾文件,就不做展示了
可以看到上面的例子,文件结构与具体的操作分离,具体的操作交由传入的访问者去决定
总结
实际上Files里已经实现了文件的遍历方法,利用的正是访问者模式
public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
throws IOException
{
return walkFileTree(start,
EnumSet.noneOf(FileVisitOption.class),
Integer.MAX_VALUE,
visitor);
}
访问者模式是为了抽象出作用于一组复杂对象的操作,并且后续可以新增操作而不必对现有的对象结构做任何改动。