O Eclipse Modeling Framework tem uma ideia interessante que também considera herança. O conceito básico é definido na interface Switch : a troca é feita invocando o método doSwitch .
O que é realmente interessante é a implementação. Para cada tipo de interesse, um
public T caseXXXX(XXXX object);
O método deve ser implementado (com uma implementação padrão retornando nulo). A implementação doSwitch tentará chamar todos os métodos caseXXX no objeto para toda a sua hierarquia de tipos. Algo nas linhas de:
BaseType baseType = (BaseType)object;
T result = caseBaseType(eAttribute);
if (result == null) result = caseSuperType1(baseType);
if (result == null) result = caseSuperType2(baseType);
if (result == null) result = caseSuperType3(baseType);
if (result == null) result = caseSuperType4(baseType);
if (result == null) result = defaultCase(object);
return result;
A estrutura atual usa um ID inteiro para cada classe, portanto, a lógica é realmente uma opção pura:
public T doSwitch(Object object) {
return doSwitch(object.class(), eObject);
}
protected T doSwitch(Class clazz, Object object) {
return doSwitch(getClassifierID(clazz), object);
}
protected T doSwitch(int classifierID, Object theObject) {
switch (classifierID) {
case MyClasses.BASETYPE:
{
BaseType baseType = (BaseType)object;
...
return result;
}
case MyClasses.TYPE1:
{
...
}
...
Você pode ver uma implementação completa do ECoreSwitch para ter uma idéia melhor.