Double Dispatch pattern is an alternative to using “instanceof” in your code.
Example
Assume this class heirarchy:
Parent -> ChildA
Parent -> ChildB
Assume a class Operator that wants to operate differently based on the type of object (ChildA or ChildB)
Operator {
execute(Parent obj) {
if (obj instanceof ChildA) {
execute((ChildA)obj)
} else if (obj instanceof ChildB) {
execute(ChildB)obj)
}
execute(ChildA child) {
//do something with A
}
execute(ChildB child) {
//something different for B
}
}
Double Dispatch
If you use double dispatch pattern, you move the execute() call to the child objects.
Operator { execute(Parent obj) { obj.runExecute(this); } }
ChildA { runExecute(Operator operator) { operator.execute(this); } }
But the downside is you have to replicate the runExecute() method above to all child classes.
Double Dispatch with Reflection
If you want to keep the runExecute method at the parent, you can use reflection to get the appropriate method and execute it.
Parent {
runExecute(Operator operator) {
Class clazz = this.getClass(); //This will return the subtype (e.g., "ChildA")
try {
Method method = operator.getClass().getMethod("execute", clazz);
method.invoke(t, this);
} catch (SecurityException e) {
} catch (....
}
}
This removes the need to write runExecute in every child class.
A little more
In case the method cannot be found for the given description, you can try the superclass type of clazz and so on.
Leave a comment