意图
表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作.
意图中的-->某对象结构:可以理解为集合,它们相当于一个聚集一样,里面可以放置多个元素,访问者模式作用于聚集中每一个元素的不同操作.
我们想修改某个对象的新操作必然要修改该对象定义的类,在类里面增加相应的方法,这样这个对象就具备了新的操作.访问者模式不需要修改这个对象对应的类就可以对该对象添加新的操作.
适用性:
1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作.
2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作"污染"这些对象的类.Visitor使得你可以将相关的操作集中起来定义在一个类中.当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作.
3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作.改变对象结构类需要重定义对搜有访问者的接口,这可能需要很大的代价.如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好.
构成:
1.抽象访问者(Visitor)角色:为对象结构类中每一个ConcreteElement的类声明一个visit操作.
2.具体访问者(ConcreteVisitor)角色:实现每个由Visitor声明的操作.
3.元素(Element)角色:定义一个Accept操作,它以一个访问者为参数.
4.具体元素(ConcreteElement)角色:实现Accept操作,该操作以一个访问者为参数.
5.对象结构类(ObjectStructure)角色(聚集角色):能枚举(遍历)它的元素.可以提供一个高层的接口以允许访问者访问它的元素.
ClassDiagram:
SequenceDiagram:
class Client { static void Main(string[] args) { ObjectStructure o = new ObjectStructure(); o.Attach(new ConcreteElementA()); o.Attach(new ConcreteElementB()); ConcreteVisitorA v1 = new ConcreteVisitorA(); ConcreteVisitorB v2 = new ConcreteVisitorB(); o.Accept(v1); o.Accept(v2); Console.ReadKey(); } } /// <summary> /// 抽象访问者 /// </summary> abstract class Visitor { public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); } /// <summary> /// 元素角色 /// </summary> abstract class Element { public abstract void Accept(Visitor visitor); } /// <summary> /// 具体元素角色A /// </summary> class ConcreteElementA : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementA(this); } } /// <summary> /// 具体元素角色B /// </summary> class ConcreteElementB : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementB(this); } } /// <summary> /// 具体访问者角色A /// </summary> class ConcreteVisitorA : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0} Visited by {1}", concreteElementA.GetType().Name, this.GetType().Name); } public override void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine("{0} Visited by {1}", concreteElementB.GetType().Name, this.GetType().Name); } } /// <summary> /// 具体访问者角色B /// </summary> class ConcreteVisitorB : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0} Visited by {1}", concreteElementA.GetType().Name, this.GetType().Name); } public override void VisitConcreteElementB(ConcreteElementB concreteElementB) { Console.WriteLine("{0} Visited by {1}", concreteElementB.GetType().Name, this.GetType().Name); } } /// <summary> /// 对象结构类 /// </summary> class ObjectStructure { private ArrayList list = new ArrayList(); public void Attach(Element element) { list.Add(element); } public void Dettach(Element element) { list.Remove(element); } public void Accept(Visitor vsistor) { foreach (Element e in list) { e.Accept(vsistor); } } }