目的是封裝一些施加于某種資料結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的資料結構則可以保持不變。
問題提出
System.Collection命名空間下提供了大量集合操作對象。但大多數情況下處理的都是同類對象的聚集。換言之,在聚集上采取的操作都是一些針對同類型對象的同類操作。但是如果針對一個儲存有不同類型對象的聚集采取某種操作該怎麼辦呢?
粗看上去,這似乎不是什麼難題。可是如果需要針對一個包含不同類型元素的聚集采取某種操作,而操作的細節根據元素的類型不同而有所不同時,就會出現必須對元素類型做類型判斷的條件轉移語句。這個時候,使用通路者模式就是一個值得考慮的解決方案。
通路者模式
通路者模式适用于資料結構相對未定的系統,它把資料結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化。
資料結構的每一個節點都可以接受一個通路者的調用,此節點向通路者對象傳入節點對象,而通路者對象則反過來執行節點對象的操作。這樣的過程叫做"雙重分派"。節點調用通路者,将它自己傳入,通路者則将某算法針對此節點執行。
雙重分派意味着施加于節點之上的操作是基于通路者和節點本身的資料類型,而不僅僅是其中的一者。
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
Console.WriteLine("{0} visited by {1}", one, 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
visitor.VisitorTwoElement(this);
//通過該類ObjectStruct把Element和visitor串聯
public class ObjectStruct
private ArrayList list = new ArrayList();
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);
注:本文引自
http://www.cnblogs.com/pursuedream/articles/795051.html