Tener una cadena de operaciones "instanceof" se considera un "olor a código". La respuesta estándar es "usar polimorfismo". ¿Cómo lo haría en este caso?Evitar instanceof en Java
Existen varias subclases de una clase base; ninguno de ellos está bajo mi control. Una situación análoga sería con las clases de Java Integer, Double, etc. BigDecimal
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);}
tengo control sobre NumberStuff y así sucesivamente.
No quiero usar muchas líneas de código donde algunas líneas harían. (A veces hago un mapeo HashMap Integer.class a una instancia de IntegerStuff, BigDecimal.class a una instancia de BigDecimalStuff etc. Pero hoy quiero algo más simple.)
me gustaría algo tan simple como esto:
public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
Pero Java simplemente no funciona de esa manera.
Me gustaría utilizar métodos estáticos al formatear. Las cosas que estoy formateando son compuestas, donde un Thing1 puede contener un array Thing2s y un Thing2 pueden contener un conjunto de Thing1s. Tenía un problema cuando he implementado mis formateadores de la siguiente manera:
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);
}
}
Sí, sé que el HashMap y un poco más de código puede arreglar eso también. Pero el "instanceof" parece tan legible y mantenible en comparación. ¿Hay algo simple pero no huele mal?
Nota añadida 5/10/2010:
Resulta que las nuevas subclases probablemente se añadirán en el futuro, y mi código existente tendrá que manejarlas con garbo. El HashMap on Class no funcionará en ese caso porque no se encontrará la clase. Una cadena de si las declaraciones, empezando por la más específica y terminando con el más general, es probablemente el mejor, después de todo:
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
}
Sugeriría un [patrón de visitante] [1]. [1]: http://en.wikipedia.org/wiki/Visitor_pattern – lexicore
¿Es la cadena ifthen a la que se opone, o simplemente el uso de "instanceof"? – Greg
El patrón Visitor requiere agregar un método a la clase objetivo (Integer por ejemplo) - fácil en JavaScript, difícil en Java. Excelente patrón al diseñar las clases objetivo; no es tan fácil cuando intentamos enseñarle a un viejo Clase nuevos trucos. –