三、示意性源代碼
// Visitor pattern -- Structural example
using System;
using System.Collections;
// "Visitor"
abstract class Visitor
{
// Methods
abstract public void VisitConcreteElementA(
ConcreteElementA concreteElementA );
abstract public void VisitConcreteElementB(
ConcreteElementB concreteElementB );
}
// "ConcreteVisitor1"
class ConcreteVisitor1 : Visitor
{
// Methods
override public void VisitConcreteElementA(
ConcreteElementA concreteElementA )
{
Console.WriteLine( "{0} visited by {1}",
concreteElementA, this );
}
override public void VisitConcreteElementB(
ConcreteElementB concreteElementB )
{
Console.WriteLine( "{0} visited by {1}",
concreteElementB, this );
}
}
// "ConcreteVisitor2"
class ConcreteVisitor2 : Visitor
{
// Methods
override public void VisitConcreteElementA(
ConcreteElementA concreteElementA )
{
Console.WriteLine( "{0} visited by {1}",
concreteElementA, this );
}
override public void VisitConcreteElementB(
ConcreteElementB concreteElementB )
{
Console.WriteLine( "{0} visited by {1}",
concreteElementB, this );
}
}
// "Element"
abstract class Element
{
// Methods
abstract public void Accept( Visitor visitor );
}
// "ConcreteElementA"
class ConcreteElementA : Element
{
// Methods
override public void Accept( Visitor visitor )
{
visitor.VisitConcreteElementA( this );
}
public void OperationA()
{
}
}
// "ConcreteElementB"
class ConcreteElementB : Element
{
// Methods
override public void Accept( Visitor visitor )
{
visitor.VisitConcreteElementB( this );
}
public void OperationB()
{
}
}
// "ObjectStructure"
class ObjectStructure
{
// FIElds
private ArrayList elements = new ArrayList();
// Methods
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 );
}
}
/**//// <summary>
/// ClIEnt test
/// </summary>
public class ClIEnt
{
public static void Main( string[] args )
{
// Setup structure
ObjectStructure o = new ObjectStructure();
o.Attach( new ConcreteElementA() );
o.Attach( new ConcreteElementB() );
// Create visitor objects
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
// Structure accepting visitors
o.Accept( v1 );
o.Accept( v2 );
}
}
結構對象會遍歷它自己所保存的聚集中的所有節點,在本系統中就是節點ConcreteElementA和節點ConcreteElementB。首先ConcreteElementA會被訪問到,這個訪問是由以下的操作組成的:
ConcreteElementA對象的接受方法被調用,並將VisitorA對象本身傳入;
ConcreteElementA對象反過來調用VisitorA對象的訪問方法,並將ConcreteElementA對象本身傳入;
VisitorA對象調用ConcreteElementA對象的商業方法OperationA( )。
從而就完成了雙重分派過程,接著,ConcreteElementB會被訪問,這個訪問的過程和ConcreteElementA被訪問的過程是一樣的。
因此,結構對象對聚集元素的遍歷過程就是對聚集中所有的節點進行委派的過程,也就是雙重分派的過程。換言之,系統有多少個節點就會發生多少個雙重分派過程。