访问者模式(Visitor): 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的 新操作。
Visitor 类,为该对象结构中ConcreteElement 的每一个类声明一个Visit操作
abstract class Visitor{
public abstract void VisitorElementA(ConcreteElementA concreteElementA);
public abstract void VisitorElementB(ConcreteElementB concreteElementB);
}
ConcreteVisitor1 和 ConcreeVisitor2 类, 具体访问者,实现每个由Visitor 声明的操作。 每个操作实现算法的一部分, 而该算法片断乃是对应于结构中对象的类。
class ConcreteVisitor1 : Visitor{
public override void VisitConcreteElementA(ConcreteElementA concreteElementA){
Console.WriteLine("{0} 被 {1}访问", concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitConcreteElementB(ConcreteElementB concreteElementB){
Console.WriteLine("{0} 被 {1}访问", concreteElementA.GetType().Name, this.GetType().Name);
}
}
class ConcreteVisitor2 : Visitor{
//代码与上类似,省略
}
Element 类,定义一个Accept操作, 它以一个访问者为参数
abstract class Element{
public abstract void Accept(Visitor visitor);
}
ConcreteElementA 和 ConcreteElementB 类, 具体元素,实现Accept 操作
class ConcreteElementA : Element{
public override void Accept(Visitor visitor){
visitor.VisitConcreteElementA(this);
}
public void OperationA()
{} //其他相关方法
}
class ConcreteElementB : Element{
public override void Accept(Visitor visitor){
visitor.VisitConcreteElementA(this);
}
public void OperationB() //其他相关方法
{}
}
ObjectStructure 类, 能枚举它的元素, 可以提供一个高层次的接口以允许访问者访问它的元素
class ObjectStucture{
private IList<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 e in elements){
e.Accept(visitor);
}
}
}
客户端代码:
static void Main(string[] args){
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
o.Accept(v1);
o.Accept(v2);
Console.Read();
}
访问者模式的能力和复杂性是一把双刃剑, 只有当你真正需要它的时候,才考虑使用它。