• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Double Dispatching

 
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear Freinds,
I have read that Visitor pattern is working with double dispathing. That is 'B' calling a method of 'A', passing 'this/B' as a parameter and A in effect calling a function on B.
Can anybody tell me exactlty the demanding situations where we use double dispatching??
thanx in advance
Binu K Idicula
 
author
Posts: 11962
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why "demanding situations"?
The Visitor pattern is not (in my opinion) intended for demanding situation any more than other behavioral patterns.
Anyway, the Visitor pattern is often used in situations where the designer wants to avoid bloating the target of the visitor. You could say that with the Visitor pattern, you can add functionality to a class without it knowing.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would rather say that you use Visitor to add polymorphic behaviour to a whole class hierarchy without it knowing.
This is one use of Double Dispatch - another is a workaround to get polymorphic behaviour on method arguments in languages without Multi Methods (like Java).
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Double dispatch is yet another way to reduce coupling between objects.
The following examples are not anything you would do in Java because there are already perfectly good number classes, but they are the classic textbook examples ...
Say you had a bunch of number classes: MyInt, MyDouble, MyLong, etc. They all implement MyNumber which requires a method add. The code in MyInt.add might look like:

OO folks usually hold their noses at long switch statements like that, and instance of for that matter. So double-dispatch does this:

First - see how this works? Every class has an addMyInt method that knows how to add to a MyInt. No nasty switches anywhere. Second - see the "double" part here? We "dispatched" an add request to MyInt, and MyInt "dispatched" another request to the argument.
Now when we introduce a new type to the system, say MyDecimal, we add a method to each class that knows how to add MyDecimal to itself instead of adding to nasty switch statements in every class.
BTW: I'm a fan of visitor. Here's a little paper I wrote about Real Life Examples.
 
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm sure there are good uses for the Double dispatch pattern, but I'll give you a word of warning with it's implementation. We attempted to use this for a message processor mechanism in order to avoid lage unmanagable switch statements in our java code.
This pattern works well if all of your project is in one module, but when your double dispatch crosses multiple modules, circular dependencies become unmanagable.
We refactored into using a property driven abstract class method that used a small amount of reflections to call the appropriate method.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Robert Martin wrote an article a while back about cyclic dependencies in the Visitor pattern and proposed a way around the problem.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm, that's a C++ oriented article. Isn't it easier in Java?
In the package or module that houses the elements to be visited, define a visitor interface or base visitor class. Implement the interface or extend the base class in any number of other modules. The elements have no compile-time dependency on any concrete visitor.
For example I wrote some visitors to work with a DOM provided by another party by extending his base visitor. I know he didn't have any dependencies on my code!
BTW: Here's a scholarly definition of visitor: "The purpose of the Visitor Pattern is to encapsulate an operation that you want to perform on the elements of a data structure. In this way, you can change the operation being performed on a structure without the need of changing the classes of the elements that you are operating on." Leaves me scratchin my head.
I usually get more concrete - Visitor is a way to iterate over a set of objects without knowing exactly how they are put together. Might be a tree, might be a linked list, but either way the visitor is eventually visits all of em.
And "encapsulate an operation" sounds like another pattern ... isn't a visitor a command?
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Stan James:
Hmmm, that's a C++ oriented article. Isn't it easier in Java?


I don't think so.


In the package or module that houses the elements to be visited, define a visitor interface or base visitor class. Implement the interface or extend the base class in any number of other modules. The elements have no compile-time dependency on any concrete visitor.


They also don't have it in the C++ version. But they do have a dependency on the visitor interface. And the visitor is depending on the element base class - therefore the cyclic dependency.


For example I wrote some visitors to work with a DOM provided by another party by extending his base visitor. I know he didn't have any dependencies on my code!


But *you* had not only to recompile, but even do change your visitor if they decided the visitor should be able to handle another type of element. Not so with the acyclic visitor.

BTW: Here's a scholarly definition of visitor: "The purpose of the Visitor Pattern is to encapsulate an operation that you want to perform on the elements of a data structure. In this way, you can change the operation being performed on a structure without the need of changing the classes of the elements that you are operating on." Leaves me scratchin my head.


Why?
By implementing a visitor on the DOM above, you wrote an operation on that DOM without having to touch the DOM classes. Still scratching?

I usually get more concrete - Visitor is a way to iterate over a set of objects without knowing exactly how they are put together. Might be a tree, might be a linked list, but either way the visitor is eventually visits all of em.


Doesn't sound like visitor to me...
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, I think maybe I was looking at cyclic dependencies between packages and you were looking within. Is that right? I guess I had chosen to live with the internal cycle.
Won't Element and the Visitor Interface always reference each other? Are there ways around that? (Not going to try to follow the C++ examples, sorry.) Is it a big deal?
My complaint with that other defintiion of visitor (forget where I found it) was that it was so abstract it meant nearly nothing. Yeah, my definition still sucked. The one from the inside cover of GoF is better: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation wtihout changing the classes of the elements on which it operates.
Here is some more about my experience with Visitor.
OptimalJ has a nice overview of Package Design principles. And a tool to measure how well you're doing with them.
[ June 16, 2003: Message edited by: Stan James ]
[ June 16, 2003: Message edited by: Stan James ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Stan James:
Ah, I think maybe I was looking at cyclic dependencies between packages and you were looking within. Is that right?


Well, I (and as far as I understand, Robert Martin, too) was talking about class dependencies in general.

I guess I had chosen to live with the internal cycle.


Probably you can often do so without much worry. But it *might* hurt you later, for example in the form of increased compilation times.

Won't Element and the Visitor Interface always reference each other? Are there ways around that? (Not going to try to follow the C++ examples, sorry.) Is it a big deal?


Using the ACV, the visitor interface doesn't reference the element. Just take a look at figure 3 on page 3 and think of "<methodname>=0" as an abstract method and dynamic_cast as a form of instanceof.

My complaint with that other defintiion of visitor (forget where I found it) was that it was so abstract it meant nearly nothing. [...] The one from the inside cover of GoF is better: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation wtihout changing the classes of the elements on which it operates.


Isn't that in fact the same definition, only using slightly different words?

Here is some more about my experience with Visitor.


I think you are mixing two things here.
The Visitor pattern is solely about using Double Dispatch to define an operation on a class hierarchy without having to touch the original classes. Iterating over a complex data structure *is not* part of the visitor pattern.
With other words: the most general accept method looks like

Adding code for also visiting child nodes or the like is already a variation.
BTW, your link titled "Visitor pattern considered useless" is miss-titled - the paper is called "Visitor versus Multimethods". In the absence of multimethods (as in Java), Visitor is just sometimes the best workaround.


OptimalJ has a nice overview of Package Design principles. And a tool to measure how well you're doing with them.


You can read more about those principles at http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign and in Robert C. Martins very recomendable book "Agile Software Development - Principles, Patterns and Practices".
An open source project which will also give you metrics based on those principles is JDepend: http://www.clarkware.com/software/JDepend.html (it will also integrate seemlessly into tools like Ant and Eclipse).
Those are, of course, not the only ones...
 
I child proofed my house but they still get in. Distract them with this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic