Implementing the Visitor Pattern
So, now you have Job, Resume, and Advertisement classes that inherit from Listing (and indirectly Host) and each has an implementation of the Accept
method. That's the easiest part. The utility depends on how you implement the Visitor. Listing 2
shows an example of a Job, Resume, Advertisement, and Listing Visitor class.
Because Visitor is an abstract class, you have to implement each of the abstract Visit
methods, as shown in Listing 2
. The real work is done in the other members you add to the Visitor. This example gets the ListingCount
, and the AverageDaysRemaining
for each Listing, whether the listing is a Job, Resume, or Advertisement. Keep in mind that you could easily define future Visitors to do other things without ever changing the implementation of the hosts.
|Figure 1. Output from the Console Application: This figure shows statistics obtained by using the Visitor pattern to extract information from sample Listing objects.|
contains a sample console application that populates an array of Listings with some random Jobs, Resumes, and Advertisements. Next, it visits each Listing and gathers information using a Visitor and displays the results (see Figure 1
You could probably achieve the same result by creating a typed collection of Listing objects, but you would have to change the typed collection each time you wanted to add new information-gathering features. Using the Visitor pattern eliminates this need. Even more beneficial would be to define Host and Visitor as interfaces, which would permit Visitor implementations to visit classes that do not have a common ancestor, and therefore would not fit neatly into a typed collection.
To recap, when you use the Visitor pattern, each class that plays host needs only a very simple Accept method. You can define as many visitors as you'd like at some arbitrary future time, and have them invoke any operation or gather any information you wish without changing the hosts. The result is that your hosts remain stable, while still supporting future additions. It is important to note that the hosts can be persisted classes and the GUI can be anything; I used simple hosts and a simple console application to avoid muddling up the pattern code.