I've seen examples in both ways, particularly Wikipedia shows an example where the visited object decides the visiting order and I think this is a sounding approach.
I'm in a situation in which I will need several visiting orders so It seems reasonable to let the Visitor decide the visiting order. However, If the visitor is responsible for the visiting order (i.e., for calling the accept method of the object being visited) I could make the visitor just call some visiting method directly (i.e., bypass the call to the visiting object's accept method) and this seems totally contrary to what the pattern proposes..
What is the correct way to implement the visiting pattern and how to deal when we have several different visiting orders?
I believe there is no "one correct way". Correct way is the way that meets your needs.
A visitor must visit each element of the object structure. The question is, how does it get there? Who is responsible for traversing the object structure? GoF Design Patterns book answers the question as follows:
1- Often the object structure is responsible for iteration. A collection will simply iterate over its elements, calling the Accept operation on each.
2- Another solution is to use an iterator to visit the elements.
3- You could even put the traversal algorithm in the visitor, although you'll end up duplicating the traversal code in each ConcreteVisitor for each aggregate ConcreteElement. The main reason to put the traversal strategy in the visitor is to implement a particularly complex traversal, one that depends on the results of the operations on the object structure.
So it is fine to let visitor to decide visiting order.
Good question. You seem to be looking at design patterns as recipes or even algorithms, when they're really just a way of discussing things that programmers do all the time. There's no right way to implement a pattern.
In the case of the Visitor pattern, the point of invoking accept
on the visited object is that each visited object may have a different internal structure. In such a case (for example, the syntax tree of a program), it makes sense to hide this internal structure from the visitor. In other cases the structure of the visited data is homogeneous, such as an XML document, it makes perfect sense for the visitor to decide the order.
In cases where the visited objects have varying internal structure but you want to visit them in different orders, you can have different accept
methods (acceptPreOrder
and acceptPostOrder
) to visit, for example, the node and then it's children or the children and then the node. To keep things simple, you could also have a single accept method that takes an order
parameter. This is problematic as well, because the visited objects need to implement all possible traversal orders. If the visitor knows enough about the structure of the visited objects to decide on a traversal order, it may in fact be better to let the visitor handle visiting children of a given object directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With