用途
访问者模式 (Visitor)
表示一个作用于某对象结构中的各元素的操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式是一种行为型模式。
用途
图-访问者模式结构图
Visitor : 为该对象结构中 ConcreteElement 的每一个类声明一个 Visit 操作。
abstract class Visitor {
public abstract void VisitConcreteElementA(ConcreteElementA elementA);
public abstract void VisitConcreteElementB(ConcreteElementB elementB);
}
public abstract void VisitConcreteElementA(ConcreteElementA elementA);
public abstract void VisitConcreteElementB(ConcreteElementB elementB);
}
ConcreteVisitor : 实现每个由 Visitor 声明的操作。每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。
class ConcreteVisitor1 extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA elementA) {
System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
}
@Override
public void VisitConcreteElementB(ConcreteElementB elementB) {
System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
}
}
class ConcreteVisitor2 extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA elementA) {
System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
}
@Override
public void VisitConcreteElementB(ConcreteElementB elementB) {
System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
}
}
@Override
public void VisitConcreteElementA(ConcreteElementA elementA) {
System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
}
@Override
public void VisitConcreteElementB(ConcreteElementB elementB) {
System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
}
}
class ConcreteVisitor2 extends Visitor {
@Override
public void VisitConcreteElementA(ConcreteElementA elementA) {
System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());
}
@Override
public void VisitConcreteElementB(ConcreteElementB elementB) {
System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());
}
}
Element : 定义一个Accpet操作,它以一个访问者为参数。
abstract class Element {
public abstract void Accept(Visitor visitor);
}
public abstract void Accept(Visitor visitor);
}
ConcreteElement : 实现 Element 声明的 Accept 操作。
class ConcreteElementA extends Element {
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementA(this);
}
}
class ConcreteElementB extends Element {
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementB(this);
}
}
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementA(this);
}
}
class ConcreteElementB extends Element {
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementB(this);
}
}
ObjectStructure : 可以枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。
class ObjectStructure {
private List<Element> elements = new ArrayList<Element>();
public void Attach(Element element) {
elements.add(element);
}
public void Detach(Element element) {
elements.remove(element);
}
public void Accept(Visitor visitor) {
for (Element elem : elements) {
elem.Accept(visitor);
}
}
}
private List<Element> elements = new ArrayList<Element>();
public void Attach(Element element) {
elements.add(element);
}
public void Detach(Element element) {
elements.remove(element);
}
public void Accept(Visitor visitor) {
for (Element elem : elements) {
elem.Accept(visitor);
}
}
}
测试代码
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
o.Accept(v1);
o.Accept(v2);
}
}
public static void main(String[] args) {
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
o.Accept(v1);
o.Accept(v2);
}
}
运行结果
ConcreteVisitor1 访问 ConcreteElementA
ConcreteVisitor1 访问 ConcreteElementB
ConcreteVisitor2 访问 ConcreteElementA
ConcreteVisitor2 访问 ConcreteElementB
ConcreteVisitor1 访问 ConcreteElementB
ConcreteVisitor2 访问 ConcreteElementA
ConcreteVisitor2 访问 ConcreteElementB