MrUll's

Juli 22, 2004

Basic double dispatching OO pattern

At the moment, i'm reading "J2EE Design and Development, Wrox Press"; herein the author promotes four approaches to generating XML from a set of Java Objects. (annot. backwards jakarta commons "digester" is perhaps suitable). One strategy is using the visitor pattern. i refreshed my mind on this and noticed a concept called "double dispatching" i never heared before. so i made up my mind about this. there are some statements about it and its worth to note that the Visiter is a specific double-dispatch technique.
 
ootips.org stated:
dual or double dispatch means a function call that depends on two of its arguments. OO usually supports single dispatch - the call is dynamically dispatched based on the object's type, but not on the type of any of the arguments.
 
vince huston on his site:
OO messages routinely manifest "single dispatch" - the operation that is executed depends on: the name of the request, and the type of the receiver. In "double dispatch", the operation executed depends on: the name of the request, and the type of TWO receivers (the type of the Visitor and the type of the element it visits).

With this things are getting clearer: two receivers (of a call) means that there has to be a second call. Maybe a recall to the call-generating object (initiator) or a call to an object passed as actual parameter (... a command object).  this technique allows e.g. to prevent instanceof decisions and/or downcasts  (to dispatch work based on the type). Actual parameter for the second call is often the instance of the actual object whos method is called - this.

use double dispatch for a highlevel separation of concerns (or to obfuscate code ...). 
If code like this is present:

public class DocWorkflow implements iDocWorkflow {
...
public void shiftToNextView( businessDocument doc) {

  if(doc instanceof businessTextDoc) { 
       this.shiftToCatalogueDept((businessTextDoc) doc);
       ...
  }
if(doc instanceof businessPricingDoc) ....
}
...
private void shiftToCatalogueDept( businessTextDoc x) { ... }

private void shiftToPurchasingDept( businessPricingDoc x) { ... }
... 

to introduce double dispatch: why not let the specific document type itself decide which concrete step is next ? (imagine 45 doc types and some additional special code, maybe a doc split or hiding some data ...). This would result in a large spaghetticode. first is to change private shift methods to protected to allow access. then, introduce a backward call:

public shiftToNextView( businessDocument doc) {
  ...
  doc.shiftToNextView(this);
  ...
}

in e.g. class businessTextDoc (subclass of businessDocument):

protected shiftToNextView( iDocWorkflow iwf ) {

iwf.shiftToCatalogueDept(this);

}

With this, no downcasting is required any more (potential risks at runtime)