Ter uma cadeia de operações "instanceof" é considerado um "cheiro de código". A resposta padrão é "use polimorfismo". Como eu faria isso neste caso?
Existem várias subclasses de uma classe base; nenhum deles está sob meu controle. Uma situação análoga seria com as classes Java Integer, Double, BigDecimal etc.
if (obj instanceof Integer) {NumberStuff.handle((Integer)obj);}
else if (obj instanceof BigDecimal) {BigDecimalStuff.handle((BigDecimal)obj);}
else if (obj instanceof Double) {DoubleStuff.handle((Double)obj);}
Eu tenho controle sobre NumberStuff e assim por diante.
Não quero usar muitas linhas de código onde algumas linhas serviriam. (Às vezes eu faço um HashMap mapeando Integer.class para uma instância de IntegerStuff, BigDecimal.class para uma instância de BigDecimalStuff etc. Mas hoje eu quero algo mais simples.)
Eu gostaria de algo tão simples quanto isto:
public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
Mas Java simplesmente não funciona dessa maneira.
Eu gostaria de usar métodos estáticos durante a formatação. As coisas que estou formatando são compostas, em que Thing1 pode conter um array Thing2s e um Thing2 pode conter um array de Thing1s. Tive um problema quando implementei meus formatadores como este:
class Thing1Formatter {
private static Thing2Formatter thing2Formatter = new Thing2Formatter();
public format(Thing thing) {
thing2Formatter.format(thing.innerThing2);
}
}
class Thing2Formatter {
private static Thing1Formatter thing1Formatter = new Thing1Formatter();
public format(Thing2 thing) {
thing1Formatter.format(thing.innerThing1);
}
}
Sim, eu conheço o HashMap e um pouco mais de código pode consertar isso também. Mas o "instanceof" parece tão legível e sustentável em comparação. Existe algo simples, mas não fedorento?
Nota adicionada em 10/05/2010:
Acontece que novas subclasses provavelmente serão adicionadas no futuro e meu código existente terá que lidar com elas normalmente. O HashMap na classe não funcionará nesse caso porque a classe não será encontrada. Uma cadeia de instruções if, começando com a mais específica e terminando com a mais geral, é provavelmente a melhor, afinal:
if (obj instanceof SubClass1) {
// Handle all the methods and properties of SubClass1
} else if (obj instanceof SubClass2) {
// Handle all the methods and properties of SubClass2
} else if (obj instanceof Interface3) {
// Unknown class but it implements Interface3
// so handle those methods and properties
} else if (obj instanceof Interface4) {
// likewise. May want to also handle case of
// object that implements both interfaces.
} else {
// New (unknown) subclass; do what I can with the base class
}
[text](link)
para postar links em comentários.