1.前言
访问者模式是23中设计模式中最复杂的一个,是一种将数据操作与数据结构分离的设计模式,幸运的是它的使用频率并不高。
访问者模式适合用于数据结构相对稳定的系统。
访问者模式的优点就是增加新的操作很容易,增加新的操作意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中去了。
缺点就是使增加新的数据结构变得困难了。
2.定义
访问者模式:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
3.UML图
4.访问者模式基本代码
/**
* Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作
*/
public abstract class Visitor {
public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
}
/**
* ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。
* 每个操作实现算法的一部分,而该算法片断乃是对应于结构中对象的类
*/
public class ConcreteVisitor1 extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
}
@Override
public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
}
}
public class ConcreteVisitor2 extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
}
@Override
public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
}
}
/**
* Element类,定义一个Accept操作,它以一个访问者为参数
*/
public abstract class Element {
public abstract void Accept(Visitor visitor);
}
/**
* ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作
*/
public class ConcreteElementA extends Element {
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementA(this);
}
/**
* 其他相关方法
*/
public void OperationA(){
}
}
public class ConcreteElementB extends Element {
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementB(this);
}
/**
* 其他相关方法
*/
public void OperationB(){
}
}
/**
* ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
*/
public class ObjectStructure {
private List<Element> elements = new ArrayList<>();
public void Attach(Element element){
elements.add(element);
}
public void Detach(Element element){
elements.remove(element);
}
public void Accept(Visitor visitor){
for (Element e : elements) {
e.Accept(visitor);
}
}
}
客户端代码
public class VisitorActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.Attach(new ConcreteElementA());
objectStructure.Attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
objectStructure.Accept(v1);
objectStructure.Accept(v2);
}
}