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);
...
}
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)

0 Comments:
Kommentar veröffentlichen
<< Home