Re: When and where to use Visitor Pattern?



"Daniel Parker" <danielaparker@spam?nothanks.windupbird.com> wrote in
news:FTEbe.5158$BW6.703155@xxxxxxxxxxxxxxxxxxxxx:

> "Rich MacDonald" <rich@@clevercaboose.com> wrote in message
> news:Xns9644C928CC626richclevercaboosecom@xxxxxxxxxxxxxxx
>> "Ilja Preuß" <it@xxxxxxxxxxxxx> wrote in
>> news:426ba2dc@xxxxxxxxxxxxxxxxxxxxxxx:
>>
>> Or the fact that that original class(es) needs to "do a hundred
>> things". Rather than add all that stuff into the class and create a
>> mess, you keep it lean and delegate off to a hundred visitors.
>>
>> Done well, I consider it the most useful and powerful pattern I know.
>
> I think it's fair to point out, though, that this sentiment is not
> universal, see for example http://nice.sourceforge.net/visitor.html.

Is there any universal sentiment :-?

I agree that multimethods improve the "shorter, natural, and less
obcure" sentiments. However, its the concept of Visitor separation that I
find so powerful, not the implementation choices/compromises.

> To the extent that the vistor pattern is just a poor man's substitute
> for multimethods, wouldn't "instanceof" do just as well? And be a
> little clearer? With less clutter in the core class (no visit
> method)?

"instanceof" would not do as well, imho.(*) All I'd wind up doing is
writing a big case statement at the start and delegating to sub-methods
anyway. And since many of my methods would break on "top level objects",
(e.g., don't do anything further if the class is a subclass of FOO) I'd
have to write this big case statement to call sub- case statements at
each level.

(*) It may be that "instanceof" is such a despicable eyesore to me that
I'm not being objective :-) You'll have to be the judge.

I always write an abstract class to do nothing on all the visitFoo(Foo f)
methods. Then I have abstract subclasses which do depth-first, breadth-
first, top-down, bottom up, etc. And all of these stub methods default to
calling the superclass methods so I can write stub methods at any point
in the class hierarchy, e.g., visitFooSub1(FooSub1 fooSub1){visitFoo
(fooSub1);} and I can override visitFoo. And the superclass maintains a
Collection of visited objects so I can toggle
(visitOnce/visitMany/breakImmediately). The key being to separate the
navigation from the action.

Then I have concrete subclasses of these classes as inner classes of some
other "master" class, which actually does the useful stuff. Typically,
these concrete subclasses have one-liner methods. Obscure I admit when
you first encounter the code, but amazingly powerful and elegant when you
see it at work. Big woody powerful :-) Just little fragments of classes
that together handle significant complexities.

Serialization to multiple targets, depth-all-cloning, searches,
filtering, numeric function differentiation and integration, interval
arithmethic, DataJunction-like reading and writing of arbitrary data
files...I've written 30+ significant examples of both core functionality
and custom needs. I'm continually blown away by the power and elegance of
the solutions. No comparison to the cumbersome alternatives of
"standard" OO *in those situations*. Of course, usual caveats here:
Visitor is a really dumb hammer for a lot of nails. But my experience
with it convinces me that (1) Visitor is a great solution for a helluva
lot more things than is commonly appreciated, and (2) those who dismiss
Visitor don't appreciate it ;-)

Note: My background is engineering and numerical methods and all my early
OO learning was fraught with my domain knowledge that "the functions
matter as much as the data and are a lot harder", which was completely
unappreciated in the early 90s of OO education. I only found satisfaction
when I went my own way and promoted functions to first-class objects.
Visitor (as an extension of double-dispatch) was the main outgrowth for
this. So it was from a fairly rare background that I applied the same
approaches to "common" programming problems such as cloning.

....which is not to say that multimethods suck...frankly I unfortunately
don't use languages that have them so I cannot reliably thought-
experiment a comparison with Visitor. But its the separation of functions
and objects that matters, not the syntax.
.


Quantcast