1 / 25

Visitor Pattern

Visitor Pattern. http://www.k.hosei.ac.jp/~yukita/. Visitor Pattern の目的. データ構造と処理の分離. 例題のクラス図. Uses. Uses. Uses. Visitor.java. public abstract class Visitor { public abstract void visit(File file); public abstract void visit(Directory directory); }. Acceptor.java.

tana-weeks
Download Presentation

Visitor Pattern

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Visitor Pattern http://www.k.hosei.ac.jp/~yukita/

  2. Visitor Pattern の目的 • データ構造と処理の分離 Visitor Pattern

  3. 例題のクラス図 Uses Uses Uses Visitor Pattern

  4. Visitor.java public abstract class Visitor { public abstract void visit(File file); public abstract void visit(Directory directory); } Visitor Pattern

  5. Acceptor.java public interface Acceptor { public abstract void accept(Visitor v); } Visitor Pattern

  6. Entry.java (1) import java.util.Iterator; public abstract class Entry implements Acceptor { public abstract String getName(); public abstract int getSize(); public Entry add(Entry entry) throws FileTreatmentException { throw new FileTreatmentException(); } Visitor Pattern

  7. Entry.java (2) public Iterator iterator() throws FileTreatmentException { throw new FileTreatmentException(); } public String toString() { return getName() + " (" + getSize() + ")"; } } Visitor Pattern

  8. Entry におけるダミー実装 • add, iterator メソッドは File ではエラーとなる。 • add, iterator メソッドは Directory で意味をもつ。 Visitor Pattern

  9. File.java (1) public class File extends Entry { private String name; private int size; public File(String name, int size) { this.name = name; this.size = size; } public String getName() { return name; } Visitor Pattern

  10. File.java (2) public int getSize() { return size; } public void accept(Visitor v) { v.visit(this); } } Visitor Pattern

  11. Directory.java (1) import java.util.Iterator; import java.util.Vector; public class Directory extends Entry { private String name; private Vector dir = new Vector(); public Directory(String name) { this.name = name; } public String getName() { return name; } Visitor Pattern

  12. Directory.java (2) public int getSize() { int size = 0; Iterator it = dir.iterator(); while (it.hasNext()) { Entry entry = (Entry)it.next(); size += entry.getSize(); } return size; } public Entry add(Entry entry) { dir.add(entry); return this; } Visitor Pattern

  13. Directory.java (3) public Iterator iterator() { return dir.iterator(); } public void accept(Visitor v) { v.visit(this); } } Visitor Pattern

  14. ListVisitor.java (1) import java.util.Iterator; public class ListVisitor extends Visitor { private String currentdir = ""; public void visit(File file) { System.out.println(currentdir + "/" + file); } Visitor Pattern

  15. ListVisitor.java (2) public void visit(Directory directory) { System.out.println(currentdir + "/" + directory); String savedir = currentdir; currentdir = currentdir + "/" + directory.getName(); Iterator it = directory.iterator(); while (it.hasNext()) { Entry entry = (Entry)it.next(); entry.accept(this); } currentdir = savedir; } } Visitor Pattern

  16. Visitorが処理を担当 • Visitor インタフェースを実装しているListVisitor が処理を担当する。 • 一方,Acceptor 側の File, Directory は処理を担わず,データの保持だけに責任をもつ。 Visitor Pattern

  17. FileTreatmentException.java public class FileTreatmentException extends RuntimeException { public FileTreatmentException() { } public FileTreatmentException(String msg) { super(msg); } } Visitor Pattern

  18. Main.java (1) public class Main { public static void main(String[] args) { try { System.out.println("Making root entries..."); Directory rootdir = new Directory("root"); Directory bindir = new Directory("bin"); Directory tmpdir = new Directory("tmp"); Directory usrdir = new Directory("usr"); Visitor Pattern

  19. Main.java (2) rootdir.add(bindir); rootdir.add(tmpdir); rootdir.add(usrdir); bindir.add(new File("vi", 10000)); bindir.add(new File("latex", 20000)); rootdir.accept(new ListVisitor()); System.out.println(""); System.out.println("Making user entries..."); Visitor Pattern

  20. Main.java (3) Directory yuki = new Directory("yuki"); Directory hanako = new Directory("hanako"); Directory tomura = new Directory("tomura"); usrdir.add(yuki); usrdir.add(hanako); usrdir.add(tomura); yuki.add(new File("diary.html", 100)); yuki.add(new File("Composite.java", 200)); Visitor Pattern

  21. Main.java (4) hanako.add(new File("memo.tex", 300)); tomura.add(new File("game.doc", 400)); tomura.add(new File("junk.mail", 500)); rootdir.accept(new ListVisitor()); } catch (FileTreatmentException e) { e.printStackTrace(); } } } Visitor Pattern

  22. Making root entries... /root (30000) /root/bin (30000) /root/bin/vi (10000) /root/bin/latex (20000) /root/tmp (0) /root/usr (0) Making user entries... /root (31500) /root/bin (30000) /root/bin/vi (10000) /root/bin/latex (20000) /root/tmp (0) /root/usr (1500) /root/usr/yuki (300) /root/usr/yuki/diary.html (100) /root/usr/yuki/Composite.java (200) /root/usr/hanako (300) /root/usr/hanako/memo.tex (300) /root/usr/tomura (900) /root/usr/tomura/game.doc (400) /root/usr/tomura/junk.mail (500) 実行結果 Visitor Pattern

  23. Main Sequence Diagram :Directory :File :File new :ListVisitor accept visit accept visit accept visit Visitor Pattern

  24. パターン Visitor Pattern

  25. 注意 • ConcreteVisitor の追加は簡単 • このときConcreteAcceptorの変更は不要 • ConcreteAcceptor の使いは困難 • 例えば Entry のサブクラス Device を追加しようとすれば Visit(Device)メソッドが Visitor側に必要になる。 Visitor Pattern

More Related