定义:
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
UML类图:
具体代码:
public abstract class Visitor {
abstract void visitorConcreteElementA();
abstract void visitorConcreteElementB();
}
public class ConcreteVisitorA extends Visitor {
@Override
public void visitorConcreteElementA() {
System.out.println("A");
}
@Override
void visitorConcreteElementB() {
System.out.println("B");
}
}
public class ConcreteVisitorB extends Visitor {
@Override
public void visitorConcreteElementA() {
}
@Override
public void visitorConcreteElementB() {
}
}
public abstract class Element {
public abstract void accept(Visitor visitor);
}
public class ConcreteElementA extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitorConcreteElementA();
}
public void operation() {
}
}
public class ConcreteElementB extends Element {
@Override
public void accept(Visitor visitor) {
visitor.visitorConcreteElementB();
}
public void operation() {
}
}
public class ObjectStructure {
private ArrayList<Element> list = new ArrayList<Element>(); //定义一个集合用于存储元素对象
public void accept(Visitor visitor) {
Iterator i=list.iterator();
while(i.hasNext())
{
((Element)i.next()).accept(visitor); //遍历访问集合中的每一个元素
}
}
public void addElement(Element element) {
list.add(element);
}
public void removeElement(Element element) {
list.remove(element);
}
}
模块说明:
Visitor:抽象类或者接口,声明visit方法中的参数定义哪些对象是可以被访问的。
ConcreteVisitor:具体访问者实现的对象,实现被添加到对象结构中的功能。
Element:接口或者抽象类,定义接受访问的接口。
ConcreteElement:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
ObjectStructure:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色。
适用场景:
一个对象结构包含多个类型的对象,希望对这些对象实施一些依赖其具体类型的操作。在访问者中针对每一种具体的类型都提供了一个访问操作,不同类型的对象可以有不同的访问操作。 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。访问者模式使得我们可以将相关的访问操作集中起来定义在访问者类中,对象结构可以被多个不同的访问者类所使用,将对象本身与对象的访问操作分离。
对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
优缺点:
优点:
扩展性
复用性
分离无关行为
缺点:
对象结构复杂
总结:
预留给回调实现