访问者模式:访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。

名称 Visitor
结构  
意图 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性
  • 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Vi s i t o r 使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Vi s i t o r 模式让每个应用仅包含需要用到的操作。
  • 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
Code Example
  1// Visitor
  2
  3// Intent: "Represent an operation to be performed on the elements of an 
  4// object structure. Visitor lets you define a new operation without 
  5// changing the classes of the elements on which it operates." 
  6
  7// For further information, read "Design Patterns", p331, Gamma et al.,
  8// Addison-Wesley, ISBN:0-201-63361-2
  9
 10/* Notes:
 11 * If you have a number of elements, and wish to carry out a number of
 12 * operations on them, the Visitor design pattern can be helpful.
 13 * 
 14 * It lets you extract the operations to be carried out on elements from
 15 * the elements themselves. It means operations cna change without affecting
 16 * the elements. 
 17 */

 18 
 19namespace Visitor_DesignPattern
 20{
 21    using System;
 22
 23    abstract class Visitor 
 24    {
 25        abstract public void VisitElementA(ConcreteElementA a);
 26        abstract public void VisitElementB(ConcreteElementB b);
 27    }

 28
 29    class ConcreteVisitor1 : Visitor
 30    {
 31        override public void VisitElementA(ConcreteElementA a)
 32        {
 33            
 34        }

 35
 36        override public void VisitElementB(ConcreteElementB b)
 37        {
 38            
 39        }

 40    }

 41
 42    abstract class Element 
 43    {
 44        abstract public void Accept(Visitor v);
 45    }

 46
 47    class ConcreteElementA : Element 
 48    {
 49        public Visitor myVisitor;
 50        override public void Accept(Visitor v)
 51        {
 52            myVisitor = v;            
 53        }

 54
 55        public void OperationA()
 56        {
 57            
 58        }

 59
 60        public void DoSomeWork()
 61        {
 62            // do some work here
 63            // . . .
 64
 65            // Get visitor to visit
 66            myVisitor.VisitElementA(this);        
 67
 68            // do some more work here
 69            // . . .
 70        }

 71    }

 72
 73    class ConcreteElementB : Element 
 74    {
 75        override public void Accept(Visitor v)
 76        {
 77            
 78        }

 79
 80        public void OperationB()
 81        {
 82            
 83        }

 84    }

 85
 86    /// <summary>
 87    ///    Summary description for Client.
 88    /// </summary>

 89    public class Client
 90    {
 91        public static int Main(string[] args)
 92        {            
 93            ConcreteElementA eA = new ConcreteElementA();
 94            ConcreteElementB eB = new ConcreteElementB();
 95            ConcreteVisitor1 v1 = new ConcreteVisitor1();
 96
 97            eA.Accept(v1);
 98            eA.DoSomeWork();
 99
100            return 0;
101        }

102    }

103}

104
105