» The Visitor pattern defines and performs new operations on all the elements of an existing structure, without altering its classes; » The Visitor pattern is intended for object structures, so it is often used in conjunction with the Composite pattern; the Composite pattern is responsible for setting up the multilevel structure on which the Visitor pattern then operates.
Use When:
» You have a class hierarchy that is effectively sealed; » There are many distinct operations to perform on it; » You need the flexibility to define new operations over time.
//Define the Pattern Interface and Handler Objects.
//Define the IVisitor interface to be used as the "blueprint" for the main application classes. //This interface defines the Visit() method, which accepts the object to be visited as a parameter. public interfaceIVisitor { void Visit(Element element); }
//The PrintVisitor class (object) invokes the Accept() method on the class (object) to be visited. //The visited class, in turn, invokes the Visit() method on the PrintVisitor class. //The Visit() method contains the process (code) that needs to be executed against the visited class (object) each time the object is visited. public classPrintVisitor : IVisitor { public void Print(Element element) { element.Accept(this); if (element.Child != null) { Console.Write(" ["); Print(element.Child); }
if (element.Next != null) { Print(element.Next); Console.Write("] "); } }
public void Visit(Element element) { Console.Write(" {0}", element.Weight); } }
//The StructureVisitor class (object) invokes the Accept() method on the class (object) to be visited. //The visited class, in turn, invokes the Visit() method on the StructureVisitor class. //The Visit() method contains the process (code) that needs to be executed against the visited class (object) each time the object is visited. public classStructureVisitor : IVisitor { public int Lab { get; set; } public int Test { get; set; }
public void VisitAllLabTest(Element element) { element.Accept(this); if (element.Child != null) { VisitAllLabTest(element.Child.Next); }
if (element.Next != null) { VisitAllLabTest(element.Next); } }
public void Visit(Element element) { if ((element.GetType() == typeof(MidTerm) || element.GetType() == typeof(Exam)) && element.Child == null) { Test += element.Weight; return; }
if (element.GetType() == typeof(Lab)) { Lab += element.Weight; return; }
if (element.GetType() == typeof(Test)) { Test += element.Weight; } } }
//The Context class (object) is a simple class that stores that input data to be used by the Element base class (object). public classContext { public string Input { get; set; }