I am having some trouble understanding the Visitor design pattern in respect to a tree. From my understanding, the tree itself would need an accept method that would take in a parameter of the visitor interface. As you traverse through the tree, the visitor.visit() method would need to access each node and data within the tree.
Assume the tree needs to be a private inner class.
The part I am getting hung up on is the parent class of the tree needs to have a method that will need to visit all nodes of the tree and has the visitor interface as a parameter as well.
I am still pretty new to Java and I would greatly appreciate any direction.
Although the Visitor pattern seems often to be presented in terms of walking a tree of nodes of varying runtime type, it is important to understand that the fundamental characteristic of the Visitor pattern is double dispatch. As such, the Visitor pattern is equally applicable to any situation where you want to customize behavior based on the class of an object, but don't know statically exactly what that class will be.
Example:
The
AreaVisitor
can compute the area of any shape it understands, even though the shape classes themselves provide no method for it, even when the specific type of shape is not statically known. (Look Ma, no tree!)Where you do happen to have a tree, the Visitor's various
visit()
methods can choose which child nodes to visit, or the visited nodes can make that decision in theiraccept()
methods. Which is more appropriate depends on the nature of the Visitor interface and of the types being visited. In either case, if the visitor is intended to traverse the tree in some way, then it is usual to start the process by asking the root node toaccept()
the Visitor object.If there happens to be an object representing the whole tree (other than the root node), then much the same design choice I just described must be made at that level, too. You would start the visitation by passing your visitor to some method of the container object. That method certainly has the alternative of passing the visitor on to the
accept()
method of the tree's root node. If the container happens to be of a class that the Visitor is designed for, though, then it might also have the alternative of passing itself to the appropriate one of the Visitor'svisit()
methods.Do note, however, that the Visitor pattern depends on the types that are to be distinguished by the visitor (
Circle
,Square
, andShape
in the example) to be accessible in the scope of the Visitor interface and all its concrete implementations. You can use it to visit objects of other types, but they must be subtypes of one of the types for which the Visitor was designed.