定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
类图:
- 抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的。
- 访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
- 抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。
- 元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了。
- 结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色
代码:
public abstract class Visitor { public abstract void VisitorOneElement(OneElement one); public abstract void VisitorTwoElement(TwoElement Two); } public class ConcreteOneVisitor : Visitor { public override void VisitorOneElement(OneElement one) { Console.WriteLine("{0} visited by {1}", one, this); } public override void VisitorTwoElement(TwoElement Two) { Console.WriteLine("{0} visited by {1}", Two, this); } } public class ConcreteTwoVisitor : Visitor { public override void VisitorOneElement(OneElement one) { Console.WriteLine("{0} visited by {1}", one, this); } public override void VisitorTwoElement(TwoElement Two) { Console.WriteLine("{0} visited by {1}", Two, this); } } public abstract class Element { public abstract void Accept(Visitor visitor); } public class OneElement : Element { public override void Accept(Visitor visitor) { visitor.VisitorOneElement(this); } } public class TwoElement : Element { public override void Accept(Visitor visitor) { visitor.VisitorTwoElement(this); } } //通过该类ObjectStruct把Element和visitor串联 public class ObjectStruct { private IList<Element> list = new List<Element>(); public void Attach(Element element) { list.Add(element); } public void Detach(Element element) { list.Remove(element); } //展示 public void ObjectAccept(Visitor visitor) { foreach (Element e in list) { e.Accept(visitor); } } }
调用:
ObjectStruct os = new ObjectStruct(); os.Attach(new OneElement()); os.Attach(new TwoElement()); ConcreteOneVisitor one = new ConcreteOneVisitor(); ConcreteTwoVisitor two = new ConcreteTwoVisitor(); os.ObjectAccept(one); os.ObjectAccept(two);
结果: