定义
对于一个作用于某对象结构(集合)中的各元素的操作,在不改变各元素的类的前提下定义作用于这些元素的新操作。也就是集合对象自身决定自己的操作行为。
类图
坑爹的这是,图片上传不了,熬夜不易啊
代码
1 public abstract class Element 2 { 3 public abstract void DoSomething(); 4 public void Accept(IVisitor visitor) 5 { 6 visitor.Visit(this); 7 } 8 } 9 public class House : Element 10 { 11 public override void DoSomething() 12 { 13 //TODO show your house 14 Console.WriteLine("welcome to my house!"); 15 } 16 } 17 public class Park : Element 18 { 19 public override void DoSomething() 20 { 21 //TODO enjoy yourself 22 Console.WriteLine("pick the ticket"); 23 } 24 } 25 public interface IVisitor 26 { 27 void Visit(Element e); 28 } 29 public class Friend : IVisitor 30 { 31 public void Visit(Element e) 32 { 33 //To do。。 34 Console.WriteLine("i go to visit a friend"); 35 e.DoSomething(); 36 37 } 38 } 39 public class ElementCollection 40 { 41 private IList<Element> elements = new List<Element>(); 42 public IList<Element> Elements 43 { 44 get { return elements; } 45 } 46 public void AddElement(Element e) 47 { 48 Elements.Add(e); 49 } 50 public void RemoveElement(Element e) 51 { 52 Elements.Remove(e); 53 } 54 } 55 public class VisitorClient 56 { 57 public void Test() 58 { 59 Friend friend = new Friend(); 60 ElementCollection elementCollection = new ElementCollection(); 61 //初始化集合 62 for (int i = 0; i < 10; i++) 63 { 64 if (i < 5) 65 { 66 elementCollection.AddElement(new House()); 67 } 68 else 69 { 70 elementCollection.AddElement(new Park()); 71 } 72 } 73 //集合元素接受访问 74 foreach (var item in elementCollection.Elements) 75 { 76 item.Accept(friend); 77 } 78 } 79 }
总结
有时我们会有疑问,为什么要多此一举的去通过访问对象接受访问者,在调用访问者的访问方法呢?直接访问者调用访问对象的实际方法不就ok了吗?在没有访问对象集合的时候,的确如此。但是当被访问者以集合的形式出现,而且其表现形式不一样时就麻烦了。访问者模式更加倾向于集合,类似于迭代模式,将集合内部的访问归结到其自身去执行,而不是外部去干涉。