目的:
表示要在对象结构的元素上执行的操作。访问者可让你定义新操作,而无需更改其所操作元素的类。在面向对象的程序设计和软件工程中,访问者设计模式是一种将算法与操作对象的结构分离的方法。这种分离的实际结果是能够在不修改结构的情况下向现有对象结构添加新操作。
程序示例:
考虑有一个带有军队单位的树形结构。指挥官下有两名中士,每名中士下有三名士兵。基于这个层级结构实现访问者模式,我们可以轻松创建与指挥官,中士,士兵或所有人员互动的新对象。
1.定义单位和单位访问器类型
public abstract class Unit{
private final Unit[] children;
public Unit(Unit... children) {
this.children = children;
}
public void accept(UnitVisitor visitor){
Arrays.stream(children).forEach(child->child.accept(visitor));
}
}
public interface UnitVisitor{
void visit(Commander commander);
void visit(Sergeant sergeant);
void visit(Soldier soldier);
}
2.定义具体的单元
//指挥官
public class Commander extends Unit{
public Commander(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
}
@Override
public String toString() {
return "Commander";
}
}
//中士
public class Sergeant extends Unit{
public Sergeant(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
}
@Override
public String toString() {
return "Sergeant";
}
}
//士兵
public class Soldier extends Unit{
public Soldier(Unit... children) {
super(children);
}
@Override
public void accept(UnitVisitor visitor) {
visitor.visit(this);
super.accept(visitor);
}
@Override
public String toString() {
return "Soldier";
}
}
3.定义具体的访问者
//指挥官访问者
public class CommanderVisitor implements UnitVisitor{
@Override
public void visit(Commander commander) {
System.out.println("Good to see you "+ commander);
}
@Override
public void visit(Sergeant sergeant) {
}
@Override
public void visit(Soldier soldier) {
}
}
//中士访问者
public class SergeantVisitor implements UnitVisitor{
@Override
public void visit(Commander commander) {
}
@Override
public void visit(Sergeant sergeant) {
System.out.println("Hello "+ sergeant);
}
@Override
public void visit(Soldier soldier) {
}
}
//士兵访问者
public class SoldierVisitor implements UnitVisitor{
@Override
public void visit(Commander commander) {
}
@Override
public void visit(Sergeant sergeant) {
}
@Override
public void visit(Soldier soldier) {
System.out.println("Greetings "+ soldier);
}
}
4.测试输出
Commander commander = new Commander(new Sergeant(new Soldier(), new Soldier(), new Soldier()),
new Sergeant(new Soldier(), new Soldier(), new Soldier()));
commander.accept(new SoldierVisitor());
commander.accept(new SergeantVisitor());
commander.accept(new CommanderVisitor());
/*
Greetings Soldier
Greetings Soldier
Greetings Soldier
Greetings Soldier
Greetings Soldier
Greetings Soldier
Hello Sergeant
Hello Sergeant
Good to see you Commander
*/
类图: