訪問者模式(Visitor)
定義
表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
動機
訪問者模式適用於資料結構相對穩定的系統,它把資料結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化。目地是要把處理從資料結構分離出來。
訪問者模式(Visitor)
結構圖
Visitor類,為該對象結構中ConcreteElement的每一個類聲明一個Visit操作。
abstract class Visitor
{
public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(ConcreteElementA concreteElementB);
}
ConcreteVisitor1和ConcreteVisitor1類,具體訪問者,實現每個由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}訪問", concreteElementB.GetType().Name, this.GetType().Name);
}
}
class ConcreteVisitor2 : 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}訪問", concreteElementB.GetType().Name, this.GetType().Name);
}
}
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 Operation()
{
}
}
class ConcreteElementB : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
public void Operation()
{
}
}
ObjectStructure類,能枚舉它的元素,可以提供一個高層的介面以允許訪問者訪問它的元素
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);
}