Intent
Visitor lets you define a new operation without changing the
classes of the elements on which it operates.
It would be
better if each new operation could be added separately, and the classes were independent of the operations that apply to them.
Visitor makes adding new operations easy.
A visitor gathers related operations and separates unrelated ones.
How to
Visitor
declares a Visit operation for each class of ConcreteElement
in the object structure.
ConcreteVisitor
implements each operation declared by Visitor.
Element
defines an Accept operation that takes a visitor as an argument.
ConcreteElement
implements an Accept operation that takes a visitor as an
argument.
ObjectStructure
can enumerate its elements.
UML
Code
public void remove(FileSystemComponent comp) {
throw new UnsupportedOperationException("remove");
}
public abstract long getSize();
public abstract void accept(FileSystemComponentVisitor visitor);
}
package org.haha.DesignPatterns.visitor;
public class File extends FileSystemComponent {
private long length;
public File(long length) {
this.length = length;
}
public long getSize() {
return length;
}
@Override
public void accept(FileSystemComponentVisitor visitor) {
visitor.visitFile(this);
}
}
package org.haha.DesignPatterns.visitor;
import java.util.ArrayList;
import java.util.List;
public class Directory extends FileSystemComponent {
private List<FileSystemComponent> files = new ArrayList<FileSystemComponent>();
public void add(FileSystemComponent comp) {
files.add(comp);
}
public void remove(FileSystemComponent comp) {
files.remove(comp);
}
public long getSize() {
long len = 0;
for (int i = 0; i < files.size(); i++) {
FileSystemComponent comp = files.get(i);
len += comp.getSize();
}
return len;
}
public List<FileSystemComponent> getFiles() {
return files;
}
@Override
public void accept(FileSystemComponentVisitor visitor) {
visitor.visitDirectory(this);
}
}
package org.haha.DesignPatterns.visitor;
public interface FileSystemComponentVisitor<T> {
public void visitFile(File file);
public void visitDirectory(Directory dir);
public T getResult();
}
package org.haha.DesignPatterns.visitor;
public class FileSystemComponentCountVisitor implements FileSystemComponentVisitor<Integer> {
private int count = 0;
public void visitDirectory(Directory dir) {
for (FileSystemComponent comp : dir.getFiles()) {
comp.accept(this);
}
count++;
}
public void visitFile(File file) {
count++;
}
public Integer getResult() {
return count;
}
}
package org.haha.DesignPatterns.visitor;
public class TestVisitor {
public static void main(String[] args) {
FileSystemComponent file;
file = new File(10);
FileSystemComponent dir = new Directory();
dir.add(file);
file = new File(20);
dir.add(file);
FileSystemComponent root = new Directory();
root.add(dir);
file = new File(30);
root.add(file);
FileSystemComponentVisitor visitor = new FileSystemComponentCountVisitor();
root.accept(visitor);
System.out.println(visitor.getResult());
}
}
Konwn cases
(1)向已有的稳定的类结构添加新操作
(2)聚集一个功能的相关操作