Java Tutorial/Design Pattern/Visitor Pattern
Use Visitor pattern to walk through file system
<source lang="java">
import java.io.File; public class VisitorTester {
public static void main(String[] args) { DirectoryNode node = new DirectoryNode(new File("..")); node.visit(new PrintVisitor()); }
} class PrintVisitor {
int level = 0; public void visitFileNode(FileNode node) { for (int i = 0; i < level; i++) System.out.print(" "); System.out.println(node.getFile().getName()); } public void visitDirectoryNode(DirectoryNode node) { for (int i = 0; i < level; i++) System.out.print(" "); System.out.println(node.getDirectory().getName()); level++; for (FileSystemNode c : node.getChildren()) c.visit(this); level--; }
} interface FileSystemNode {
void visit(PrintVisitor v);
} class FileNode implements FileSystemNode {
public FileNode(File file) { this.file = file; } public File getFile() { return file; } public void visit(PrintVisitor v) { v.visitFileNode(this); } private File file;
} class DirectoryNode implements FileSystemNode {
public DirectoryNode(File directory) { this.directory = directory; } public void visit(PrintVisitor v) { v.visitDirectoryNode(this); } public File getDirectory() { return directory; } public FileSystemNode[] getChildren() { File[] files = directory.listFiles(); FileSystemNode[] children = new FileSystemNode[files.length]; for (int i = 0; i < files.length; i++) { File f = files[i]; if (f.isDirectory()) children[i] = new DirectoryNode(f); else children[i] = new FileNode(f); } return children; } private File directory;
}</source>
Visitor, a type of multiple dispatching
<source lang="java">
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; interface Visitor {
void visit(FriendsInHighSchool g); void visit(FriendsFromNeighbour r); void visit(NewFriends c);
} interface Friend {
void accept(Visitor v);
} class FriendsInHighSchool implements Friend {
public void accept(Visitor v) { v.visit(this); }
} class FriendsFromNeighbour implements Friend {
public void accept(Visitor v) { v.visit(this); }
} class NewFriends implements Friend {
public void accept(Visitor v) { v.visit(this); }
} class Party implements Visitor {
String s; public String toString() { return s; } public void visit(FriendsInHighSchool g) { s = "FriendsInHighSchool"; } public void visit(FriendsFromNeighbour r) { s = "FriendsFromNeighbour"; } public void visit(NewFriends c) { s = "NewFriends"; }
} class Drink implements Visitor {
public void visit(FriendsInHighSchool g) { System.out.println("Drink and FriendsInHighSchool"); } public void visit(FriendsFromNeighbour r) { System.out.println("Drink and FriendsFromNeighbour"); } public void visit(NewFriends c) { System.out.println("Drink and NewFriends"); }
} class FriendsGenerator {
private static Random rand = new Random(); public static Friend newFlower() { switch (rand.nextInt(3)) { default: case 0: return new FriendsInHighSchool(); case 1: return new FriendsFromNeighbour(); case 2: return new NewFriends(); } }
} public class BeeAndFlowers {
public static void main(String args[]) { List<Friend> flowers = new ArrayList<Friend>(); for (int i = 0; i < 10; i++) flowers.add(FriendsGenerator.newFlower()); Party sval = new Party(); Iterator it = flowers.iterator(); while (it.hasNext()) { ((Friend) it.next()).accept(sval); System.out.println(sval); } Drink bee = new Drink(); it = flowers.iterator(); while (it.hasNext()) ((Friend) it.next()).accept(bee); }
}</source>