模式定义
表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。
UML类图
- 抽象访问者(Vistor)
- 具体访问者(ConcreteElement)
- 抽象元素(Element)
- 具体元素(ConcreteElement)
对象结构(ObjectStructure)
代码结构
public static class VisitorApp { public static void Run() { ObjectStructure o = new ObjectStructure(); o.Attach(new ConcreteElementA()); o.Attach(new ConcreteElementB()); // Create visitor objects ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2(); // Structure accepting visitors o.Accept(v1); o.Accept(v2); } } abstract class Visitor { public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); } class ConcreteVisitor1 : 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); } } class ConcreteVisitor2 : 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); } } abstract class Element { public abstract void Accept(Visitor visitor); } class ConcreteElementA : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementA(this); } } class ConcreteElementB : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementB(this); } } class ObjectStructure { private List<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 element in _elements) { element.Accept(visitor); } } }
情景案例
这种模式在.Net 框架中没必要按部就班的这么麻烦的用了。.Net 框架中
ForEach(Action<T> action)
遍历集合执行每个元素执行委托。public static class VisitorRealWorldApp { public static void Run() { List<string> lst = new List<string>() { "Item1", "Item2", "Item3" }; lst.ForEach(i => Console.WriteLine("方法一 " + i.ToString())); lst.ForEach(i => Console.WriteLine("方法二 " + i.ToString())); } }