Here is a summary of the ** Visitor pattern ** in the GoF design pattern.
--The English word Visitor means ** visitor **. --The Visitor pattern is a ** method that separates data structure and processing **. --Prepare a visitor class that walks through the data structure and let the visitor class handle the process. Then, when you want to add a new process, you can create a new visitor. And the data structure just needs to accept the visitor. --The GoF design patterns are classified as ** behavioral design patterns **.
A program that displays a list of directories and files.
An interface that represents a data structure that accepts instances of the Visitor class.
Element.java
public interface Element {
public abstract void accept(Visitor v);
}
This is the base class for File and Directory. Implement the Element interface.
Entry.java
public abstract class Entry implements Element {
public abstract String getName();
public String toString() {
return getName();
}
}
A class that represents a file. It will be a host for Visitors.
File.java
public class File extends Entry {
private String name;
public File(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void accept(Visitor v) {
v.visit(this);
}
}
A class that represents a directory. It will be a host for Visitors.
Directory.java
import java.util.ArrayList;
import java.util.Iterator;
public class Directory extends Entry {
private String name;
private ArrayList<Entry> dir = new ArrayList<Entry>();
public Directory(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Entry add(Entry entry) {
dir.add(entry);
return this;
}
public Iterator<Entry> iterator() {
return dir.iterator();
}
public void accept(Visitor v) {
v.visit(this);
}
}
An abstract class that represents a visitor to a file or directory.
Visitor.java
public abstract class Visitor {
public abstract void visit(File file);
public abstract void visit(Directory directory);
}
A class that displays a list of files and directories.
ListVisitor.java
import java.util.Iterator;
public class ListVisitor extends Visitor {
//Directory name currently in interest
private String currentdir = "";
//Called when visiting a file
public void visit(File file) {
System.out.println(currentdir + "/" + file);
}
//Called when visiting a directory
public void visit(Directory directory) {
System.out.println(currentdir + "/" + directory);
String savedir = currentdir;
currentdir = currentdir + "/" + directory.getName();
Iterator<Entry> it = directory.iterator();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
entry.accept(this);
}
currentdir = savedir;
}
}
This class performs the main processing.
Main.java
public class Main {
public static void main(String[] args) {
Directory workspaceDir = new Directory("workspace");
Directory compositeDir = new Directory("Visitor");
Directory testDir1 = new Directory("test1");
Directory testDir2 = new Directory("test2");
workspaceDir.add(compositeDir);
workspaceDir.add(testDir1);
workspaceDir.add(testDir2);
File element = new File("Element.java");
File entity = new File("Entity.java");
File file = new File("file.java");
File directory = new File("Directory.java");
File visitor = new File("Visitor.java");
File listVisitor = new File("ListVisitor.java");
File main = new File("main.java");
compositeDir.add(element);
compositeDir.add(entity);
compositeDir.add(file);
compositeDir.add(directory);
compositeDir.add(visitor);
compositeDir.add(listVisitor);
compositeDir.add(main);
workspaceDir.accept(new ListVisitor());
}
}
/workspace
/workspace/Visitor
/workspace/Visitor/Element.java
/workspace/Visitor/Entity.java
/workspace/Visitor/file.java
/workspace/Visitor/Directory.java
/workspace/Visitor/Visitor.java
/workspace/Visitor/ListVisitor.java
/workspace/Visitor/main.java
/workspace/test1
/workspace/test2
The Visitor pattern only complicates the process, and I feel that "If you need iterative processing, why not write a loop process in the data structure?" The purpose of the Visitor pattern is ** to separate data structures and processing **. A data structure organizes elements as a set and connects elements. Preserving that structure is one thing, and writing a process based on that structure is another. The Visitor role (List Visitor) can be developed independently of the Acceptor role (File, Directory). In other words, the Visitor pattern increases the independence of the acceptor (File, Directory) class as a ** part **. If the content of the process is implemented as a method of the File class or Directory class, the File class or Directory class will have to be modified every time a new process is added and the function is extended.
-** GoF design pattern summary **
This article and sample program were created based on the following books.
-** Introduction to design patterns learned in Java language **
It was very easy to understand and I learned a lot. Thank you. The detailed explanations of the design patterns and sample programs are written, so please take a look at the books as well.
Recommended Posts