访问者模式(Visitor) : 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.
访问者模式适用于数据结构相对稳定的系统.
它把数据结构和作用于结构上操作之间的耦合解脱开,使得操作集合可以相对自由地演化.
访问者模式的目的是要把处理从数据结构分离出来.很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的.因为访问者模式使得算法操作的变量变得容易.
访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中.
那访问者的缺点其实也就是使新增加的数据结构变得困难了.
基本代码
Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作
abstract class Visitor{ public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); }
ConcreteVisitor1和ConcreteVisitor2类,具体访问类,实现每个由Visitor声明的操作,每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类,
class ConcreteVisitor1 implements Visitor{ public void VisitConcreteElementA(ConcreteElementA concreteElementA){ System.out.println("被访问",concreteElementA.GetType().Name,this.GetType().Name) } public void VisitConcreteElementB(ConcreteElementB concreteElementB){ System.out.println("被访问",concreteElementB.GetType().Name,this.GetType().Name) } } class ConcreteVisitor2 implements Visitor{ public void VisitConcreteElementA(ConcreteElementA concreteElementA){ System.out.println("被访问",concreteElementA.GetType().Name,this.GetType().Name) } public void VisitConcreteElementB(ConcreteElementB concreteElementB){ System.out.println("被访问",concreteElementB.GetType().Name,this.GetType().Name) } }
Element类,定义一个Accept操作,它以一个访问者为参数
abstract class Element{ public abstract void Accept(Visitor visitor); }
ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作
class ConcreteElementA implements Element{ //充分利用双分派技术,实现处理与数据结构的分离 public void Accept(Visitor visitor){ visitor.VisitConcreteElementA(this); } //其他的相关方法 public void OperationA(){} } class ConcreteElementB implements Element{ //充分利用双分派技术,实现处理与数据结构的分离 public void Accept(Visitor visitor){ visitor.VisitConcreteElementB(this); } //其他的相关方法 public void OperationB(){} }
ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure{ private IList<Element> elements = new List<Element>(); public void Attach(Element element){ elements.Add(element); } public void Detach(Element element){ elements.Remove(element); } public void Accept(Visitor visitor){ foreach(Element e in elements){ e.Accept(visitor); } } }
客户端代码
ObjectStructure o = new ObjectStructure(); o.Attach(new ConcreteElementA()); o.Attach(new ConcreteElementB()); ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor1 v2 = new ConcreteVisitor2(); o.Accept(v1); o.Accept(v2);