Java Tutorial/Design Pattern/Visitor Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Use Visitor pattern to walk through file system

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;
}





Visitor, a type of multiple dispatching

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);
  }
}