Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visitor Pattern: Should the visitor or the visited object decide the visiting order?

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?

like image 640
JohnTortugo Avatar asked Nov 29 '14 21:11

JohnTortugo


2 Answers

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.

like image 137
b4da Avatar answered Dec 31 '22 07:12

b4da


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.

like image 39
jjm Avatar answered Dec 31 '22 06:12

jjm