设计模式——访问者模式
访问者模式,表示作用对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
//为该对象结构中ConcreteElement的每一个类声明一个Visit操作
abstract class Visitor
{
public abstract void VisitorConcreteElementA(ConcreteElementA concreteElementA);
public abstract void VisitorConcreteElementB(ConcreteElementB concreteElementB);
}
//具体访问者,实现每个由Visitor声明的操作。每一个操作实现算法的一部分,而该算法片段乃是对应结构中对象的类
class ConcreteVisitor1 : Visitor
{
public override void VisitorConcreteElementA(ConcreteElementA concreteElementA)
{
Console.WriteLine("{0}被{1}访问",concreteElementA.GetType().Name,this.GetType().Name);
}
public override void VisitorConcreteElementB(ConcreteElementB concreteElementB)
{
Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
}
}
class ConcreteVisitor2 : Visitor
{
public override void VisitorConcreteElementA(ConcreteElementA concreteElementA)
{
Console.WriteLine("{0}被{1}访问",
concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitorConcreteElementB(ConcreteElementB concreteElementB)
{
Console.WriteLine("{0}被{1}访问",
concreteElementB.GetType().Name, this.GetType().Name);
}
}
//定义一个Accept操作,它以一个访问者为参数
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
//ConcreteElementA和ConcreteElementB,具体元素,实现Accept操作
class ConcreteElementA : Element
{
public override void Accept(Visitor visitor)//充分利用双分派技术,实现处理与数据结构的分离
{
visitor.VisitorConcreteElementA(this);
}
public void OperationA()//其他的相关方法
{
}
}
class ConcreteElementB : Element
{
public override void Accept(Visitor visitor)//充分利用双分派技术,实现处理与数据结构的分离
{
visitor.VisitorConcreteElementB(this);
}
public void OperationB()//其他的相关方法
{
}
}
//能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure
{
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);
}