定义
封装一些作用于某种数据结构中各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
UML
角色
- Visitor : 抽象访问者接口
- Element : 被访问元素接口
- ElementA,ElementB : 具体元素,实现了Element接口
- VisitorA,VisitorB : 具体访问者,实现了Visitor接口
- ObjectStruct : 对象结构管理类,是一个较高层的结构
示例
/**
* desc : 元素接口
* Created by tiantian on 2018/9/14
*/
public interface Element {
void accept(Visitor visitor);
}
/**
* desc : 元素A
* Created by tiantian on 2018/9/14
*/
public class ElementA implements Element {
private String property1 = "Hello ";
private String property2 = "World";
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
System.out.println(visitor.getName() + " visited ElementA");
}
public String getProperty1() {
return property1;
}
public String getProperty2() {
return property2;
}
}
/**
* desc : 元素B
* Created by tiantian on 2018/9/14
*/
public class ElementB implements Element {
private String property1 = "hello ";
private String property2 = "world";
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
System.out.println(visitor.getName() + " visited ElementB");
}
public String getProperty1() {
return property1;
}
public String getProperty2() {
return property2;
}
}
/**
* desc : 访问者接口
* Created by tiantian on 2018/9/14
*/
public interface Visitor {
String getName();
void visit(ElementA e);
void visit(ElementB e);
}
/**
* desc : 具体访问者A
* Created by tiantian on 2018/9/14
*/
public class VisitorA implements Visitor {
private String name = "visitorA";
@Override
public String getName() {
return name;
}
@Override
public void visit(ElementA e) {
System.out.println(e.getProperty1() + e.getProperty2());
}
@Override
public void visit(ElementB e) {
System.out.println(e.getProperty1() + e.getProperty2());
}
}
/**
* desc : 访问者B
* Created by tiantian on 2018/9/15
*/
public class VisitorB implements Visitor{
private String name = "VisitorB";
@Override
public String getName() {
return name;
}
@Override
public void visit(ElementA e) {
System.out.println(e.getProperty1() + e.getProperty2());
}
@Override
public void visit(ElementB e) {
System.out.println(e.getProperty1() + e.getProperty2());
}
}
/**
* desc : 对象结构
* Created by tiantian on 2018/9/14
*/
public class ObjectStruct {
private List<Element> elements = new ArrayList<>();
public void add(Element e) {
elements.add(e);
}
public void show(Visitor visitor) {
for (Element e : elements) {
e.accept(visitor);
}
}
}
总结
访问者模式使数据结构对象和操纵数据结构的对象分离,从而降低了它们之间的耦合性。可以灵活的添加不同的访问者,以不同的方式访问该数据结构的各个元素。缺点是数据结构必须稳定,不能随意增加元素类型。也就是在示例中,Element元素的具体结构类型数量是恒定的且稳定的;若不稳定,增加了元素类型时,访问者接口也要发生变化,不符合开闭原则。