- 一种对象行为型模式
- 根据“合成复用原则”,系统中要尽量使用关联关系来取代继承关系
- 它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
- 通常在以下情况可以考虑使用访问者(Visitor)模式。
- 对象结构相对稳定,但其操作算法经常变化的程序。
- 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结 构。
public abstract class Visitor {
//
// public abstract void visit(File file);
//
// public abstract void visit(Directory dictionary);
public abstract void visit(Entry entry);
}
public class ListVisitor extends Visitor {
private String curDirName = "";
//
// @Override
// public void visit(File file) {
// System.out.println(curDirName + "/" + file);
// }
//
// @Override
// public void visit(Directory dictionary) {
// System.out.println(curDirName + "/" + dictionary);
// String saveDirName = curDirName;
// curDirName = curDirName + "/" + dictionary.getName();
// Iterator iterator = dictionary.iterator();
// while (iterator.hasNext()) {
// Entry next = (Entry) iterator.next();
// next.accept(this);
// }
// curDirName = saveDirName;
// }
@Override
public void visit(Entry entry) {
if (entry instanceof File) {
System.out.println(curDirName + "/" + entry);
} else if (entry instanceof Directory) {
System.out.println(curDirName + "/" + entry);
String saveDirName = curDirName;
curDirName = curDirName + "/" + entry.getName();
Iterator iterator = entry.iterator();
while (iterator.hasNext()) {
Entry next = (Entry) iterator.next();
next.accept(this);
}
curDirName = saveDirName;
}
}
}
public interface ElementOperation {
void accept(Visitor visitor);
}
public abstract class Entry implements ElementOperation {
// abstract 子类实现。不用维护一个父类的name和size字段
public abstract String getName();
// abstract 子类实现。不用维护一个父类的name和size字段
public abstract int getSize();
//该接口部分子类不实现,abstract,例如File子类
public Entry add(Entry entry) {
return null;
}
//该接口部分子类不实现,abstract,例如File子类
public Iterator iterator() {
return null;
}
@Override
public void accept(Visitor visitor) {
//交由子类 @Override实现
}
@Override
public String toString() {
return "Entry{" +
"name='" + getName() + '\'' +
", size=" + getSize() +
'}';
}
}
public class File extends Entry {
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
return size;
}
@Override
public void accept(Visitor visitor) {
super.accept(visitor);//通用策略,可以父类同名实现部分通用功能,再实现子功能
visitor.visit(this);
}
@Override
public String toString() {
return "File{" +
"name='" + name + '\'' +
", size=" + size +
'}';
}
}
public class Directory extends Entry {
private String name;
private ArrayList dirs = new ArrayList();//不指定类型的List,放多个entry(可以是file or directory)
public Directory(String name) {
this.name = name;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getName() {
return name;
}
@Override
public int getSize() {
int size = 0;
Iterator it = dirs.iterator();
while (it.hasNext()) {
Entry item = (Entry) it.next();
size += item.getSize();
}
return size;
}
@Override
public Entry add(Entry entry) {
dirs.add(entry);
return this;
}
@Override
public Iterator iterator() {
return dirs.iterator();
}
@Override
public String toString() {
return "Directory{" +
"name='" + name + '\'' +
", size=" + getSize() +
'}';
}
}
网友评论