I read a book about the visitor pattern. It gives the same class diagram as in the oodesign's website.
It says that adding new ConcreteElement classes is hard. But I didn't understand why. As I understood, the Concretevisitor defines the set of operations, which have to be used by the concreteElement. So when I add a new element, which has the same operation I defined earlier, I don't need to add anything (just the ConcreteElement itself). If I add a new element, which doesn't have the same operations I defined earlier in the visitors, I need to add a new visitor. But this I have to do in any design pattern.
Essentially, visitor pattern is kind of data manipulator, it will
In one word, visitor pattern will extend the system functionality, without touch the element class definition.
But does this mean the visitor class must be revised if new concrete element class is added? It depends, I believe, on how the visitor pattern is designed and implemented.
If separate all the visit methods of visitor into visit functors, and dynamically bind the them together, then it might be easier when extending the how system, for both visitor and visitee.
Here is an implementation of visitor pattern I wrote several years ago, the code is a bit old and not well polished, but somehow works :)
https://github.com/tezheng/visitor
This came up in an SO question just recently. To quote myself from this question, and more specifically the discussion
So yes it is often said that its hard to implement addition conrete elements (or entities), but in my opinion it is hogwash.
If you add a new concrete element, then all of your visitor classes will need to add a new
visit
method for the new element. If you didn't use visitors, you would have to add the equivalent methods to your new concrete element anyway.But adding a new method to each your visitors may be harder than adding the equivalent set of methods to a new element class. The reason is that visitors often need to traverse the element tree structure and may need to manage its own state data as it does so. Adding a new
visit
method may require modifying that state data which involves thinking about how the new method interacts with existingvisit
methods for other elements.It may be simpler to add the equivalent methods to your new element class if you didn't have visitors because you will only need to worry about the internal state of the new concrete element which is more cohesive.
Well, you have to extend all your visitors.
You have a caller, some elements that need to be visited, and an element - the visitor - that does the processing of the individual elements. Your goal is to keep the implementation of the elements and the caller fixed, and extend functionality via new visitors.
Usually you have a lot of the concrete visitors. If you add a new type of element to be processed, you will need to change all the concrete visitors to take this into account.
Why?
well, imagine that the caller is "Factory", and you have the elements "Car" and "Bike".
For operation "Paint" you have to have the methods
Likewise for operations "Assemble", "Package", "Wash" etc.
If you add an element "Scooter", all the operations have to be extended with a new method
This is a bit of work. Also you may hit the isse where the element you add is so different from the others that you canøt easily fit them to the operations.
Wikipedia (http://en.wikipedia.org/wiki/Visitor_pattern) says
That's a pretty abstract way of saying what I try to say above. Usually you'd add these methods to the elements, but if you can't you have to add the methods to somethign else, and pass that along to do the processing. This is a bit of extra work, but may be worth it, if the situation merits it.