设计模式(二十四)访问者模式
访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
优点:增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。
缺点:增加新的数据结构变得困难了。
基本代码
1 // Visitor 类,为该对象结构中 ConcreteElement 的每一个类声明一个 Visit 操作 2 abstract class Visitor 3 { 4 public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); 5 public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); 6 } 7 8 // ConcreteVisitor1 具体访问者类,实现每个由 Visitor 声明的操作。 9 // 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。 10 class ConcreteVisitor1 : Visitor 11 { 12 public override void VisitConcreteElementA(ConcreteElementA concreteElementA) 13 { 14 Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetTyep().Name); 15 } 16 public override void VisitConcreteElementB(ConcreteElementB concreteElementB) 17 { 18 Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetTyep().Name); 19 } 20 } 21 22 class ConcreteVisitor2 : Visitor 23 { 24 } 25 26 // Element 类,定义一个 Accept 操作,它以一个访问者为参数 27 abstract class Element 28 { 29 public abstract void Accept(Visitor visitor); 30 } 31 32 // ConcreteElementA 具体元素类,实现 Accept 操作 33 class ConcreteElementA : Element 34 { 35 // 充分利用双分派的技术,实现处理与数据结构的分离 36 public override void Accept(Visitor visitor) 37 { 38 visitor.VisitConcreteElementA(this); 39 } 40 41 public void OperationA() 42 { 43 } 44 } 45 46 // ConcreteElementB 具体元素类,实现 Accept 操作 47 class ConcreteElementB : Element 48 { 49 // 充分利用双分派的技术,实现处理与数据结构的分离 50 public override void Accept(Visitor visitor) 51 { 52 visitor.VisitConcreteElementB(this); 53 } 54 55 public void OperationB() 56 { 57 } 58 } 59 60 // ObjectStructure 类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素 61 class ObjectStructure 62 { 63 private IList<Element> elements = new List<Element>(); 64 65 public void Attach(Element element) 66 { 67 elements.Add(element); 68 } 69 70 public void Detach(Element element) 71 { 72 elements.Remove(element); 73 } 74 75 public void Accept(Visitor visitor) 76 { 77 foreach(Element e in elements) 78 { 79 e.Accept(visitor); 80 } 81 } 82 } 83 84 // 客户端 85 static void Main(string[] args) 86 { 87 ObjectStructure o = new ObjectStructure(); 88 o.Attach(new ConcreteElementA()); 89 o.Attach(new ConcreteElementB()); 90 91 ConcreteVisitor1 v1 = new ConcreteVisitor1(); 92 ConcreteVisitor2 v2 = new ConcreteVisitor2(); 93 94 o.Accept(v1); 95 o.Accept(v2); 96 97 Console.Read(); 98 }