Passing arguments in Visitor Pattern

Does anybody have a nice solution to passing arguments in Visitor pattern?

The Visitor pattern is used to process an object structure (such as an abstract syntax tree) in many different ways without cluttering definitions of the objects with methods needed for all different kinds of processing. Instead, each object has only one method, "void accept(Visitor v)". The method calls back a method in the Visitor that is appropriate for the object. Different kinds of processing use different Visitors, each with its own set of object-processing methods.

My problem is that I need to pass arguments or receive results from the object-processing methods, different for different kinds of processing.

One solution is to have many "accept" methods with different signatures. This beats the idea that we do not need to modify definitions of the objects if we want to introduce new kind of processing.

Another is to provide "accept" with an Object result and a sufficient number of Object arguments, to be used as necessary by different Visitors. It results in clumsy and unreadable code. Detestable.

Alternatively, one could provide fields in the objects to pass the information when needed. This frees the invocations of "accept" from dummy arguments/results, but does not seem nice.

One can also forget all about Visitor pattern, and let the processing method test the object class using "instanceof" and call the right method. But this is a pure blasphemy against everything called OO.

Is there any better way that I am too blind to see?

[1582 byte] By [RomanRedza] at [2007-9-28 7:50:41]
# 1

Sometimes you can replace Visitor with Composite. Others you may have to define set methods in your visitor and set these arguments as attributes for the Visitor which the accept method accesses. This is a pretty good link on Visitor with some sublinks on the page:

http://c2.com/cgi/wiki?VisitorPattern

swatdbaa at 2007-7-9 19:04:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

Sounds to me like you've got a case of combining different concerns into the same design. I think you're looking at multiple problems, all of which require you to process an object structure.

I'd make a general framework for processing my structure, and then use a specific interface for each problem. I would avoid re-using the Visitor pattern for multiple concerns as it leads to exactly the problems you're facing.

If you're dead-set on using the Visitor; how about having a mediator or adapter between the visited class and the Visitor that deals with the specifics of each invocation?

Personally, I think the Visitor pattern violates basic encapsulation and polymorphism - but that's just my opinion. I try to avoid using it unless I'm stuck with NO other solution.

Good luck.

larsonaa at 2007-7-9 19:04:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Thanks for the link! As I see from the comments there, and from the reply by "larsona", Visitor is not the silver bullet it is sold for. I take the advice and keep away from it.

Quite ironically, my application is just that described under "Motivation" in "GoF". I have a syntax tree and want to experiment with different ways of analyzing it and / or generating code. I don't want to modify definitions of nodes every time.

By the way, at design patterns session of OOPSLA 2000 somebody insisted that patterns are, in fact, only ways to work around missing features of a programming language. Can double dispatch be such a missing feature of Java?

RomanRedza at 2007-7-9 19:04:08 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

Maybe others have different opinions but I wouldn't agree that *all* patterns are ways to work around missing language features. I would agree that there are many cases where patterns can be a way to work around them. If you look on that site further they have a page about Double Dispatch and a Java code example.

swatdbaa at 2007-7-9 19:04:08 > top of Java-index,Other Topics,Patterns & OO Design...