Search code examples
design-patternsvisitor-pattern

Benefits of accumulating state during traversal of an object structure by a visitor in a visitor pattern and how can the visitor achieve this?


From the Visitor pattern chapter of Gof book on Design patterns :

Accumulating state. Visitors can accumulate state as they visit each element in the object structure.Without a visitor,this state would be passed as extra arguments to the operations that perform the traversal,or they might appear as global variables.

What do the authors mean by accumulating state here and how does accumulating state help ? Please give a practical example where accumulating state during the traversal process is helpful.


Solution

  • You can add fields to the visitor class and store state there.

    Example:

    class MyVisitor implements Visitor {
    
      private final List<Object> seenObjects = new ArrayList<Object>();
    
      void visitFoo(Foo f) {
        seenObjects.add(f);
      }
    
      void visitBar(Bar b) {
        seenObjects.add(b);
      }
    }
    

    I wouldn't say that storing state in the visitor "helps". Either you need the state to perform the operation, then you need to put it there, or you don't, then please don't store it.

    Without a visitor the code would usually look like this:

    class MyHandler {
    
      static void handle(Object o, List<Object> seenObjects) {
        seenObjects.add(o);
        if (o instanceof Foo) {
          // ...
        } else if (o instanceof Bar) {
          // ...
        }
        // possibly a recursive call to handle() somewhere, passing the seenObjects list
      }
    }
    

    The alternative would be to store the state in a field in the class, just like in the visitor case. This is also possible here, however, I would say that putting the state in fields is less common when not using the visitor pattern (because it's not necessary, and it is usually a good idea to try avoiding mutable state in fields).