Data Structures and Algorithms
with Object-Oriented Design Patterns in C# |
The Container interface described in the preceding section interacts closely with the Visitor interface shown in Program . In particular, the Accept method of the Container interface takes as its argument a reference to any class that implements the Visitor interface.
But what is a visitor? A shown in Program , a visitor is an object that has a Visit method and an IsDone property. Of these, the Visit method is the most interesting. The Visit method takes as its argument a reference to an object instance.
The interaction between a container and a visitor goes like this: The container is passed a reference to a visitor by calling the container's Accept method. That is, the container ``accepts'' the visitor. What does a container do with a visitor? It calls the Visit method of that visitor one-by-one for each object contained in the container.
The interaction between a Container and its Visitor are best understood by considering an example. The following code fragment gives the design framework for the implementation of the Accept method in some concrete class, say SomeContainer, that implements the Container interface:
public class SomeContainer : Container { public void Accept(Visitor visitor) { foreach (object i in this) { visitor.Visit(i); } } // ... }
The Accept method calls Visit for each object i in the container. Since Visitor is an interface, it does not provide an implementation for the Visit operation. What a visitor actually does with an object depends on the actual class of visitor used.
Suppose that we want to print all of the objects in the container. One way to do this is to create a PrintingVisitor which prints every object it visits, and then to pass the visitor to the container by calling the Accept method. The following code shows how we can declare the PrintingVisitor class which prints an object on the console.
public class PrintingVisitor : Visitor { public void Visit(object obj) { Console.WriteLine(obj); } // ... }
Finally, given an object c that is an instance of a concrete class SomeContainer that implements the Container interface, we can call the Accept method as follows:
Container c = new SomeContainer(); // ... c.accept(new PrintingVisitor());The effect of this call is to call the Visit method of the visitor for each object in the container.