Avere una catena di operazioni "instanceof" è considerato un "odore di codice". La risposta standard è "usa il polimorfismo". Come lo farei in questo caso?
Esistono numerose sottoclassi di una classe base; nessuno di loro è sotto il mio controllo. Una situazione analoga sarebbe con le classi Java Integer, Double, BigDecimal ecc.
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);}
Ho il controllo su NumberStuff e così via.
Non voglio usare molte righe di codice dove poche righe andrebbero bene. (A volte creo un HashMap mappando Integer.class su un'istanza di IntegerStuff, BigDecimal.class su un'istanza di BigDecimalStuff ecc. Ma oggi voglio qualcosa di più semplice.)
Vorrei qualcosa di semplice come questo:
public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
Ma Java semplicemente non funziona in questo modo.
Vorrei utilizzare metodi statici durante la formattazione. Le cose che sto formattando sono composte, dove una Thing1 può contenere un array Thing2s e una Thing2 può contenere un array di Thing1s. Ho avuto un problema quando ho implementato i miei formattatori in questo modo:
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ì, conosco HashMap e un po 'più di codice può risolvere anche questo. Ma l '"istanza di" sembra così leggibile e gestibile al confronto. C'è qualcosa di semplice ma non puzzolente?
Nota aggiunta il 5/10/2010:
Si scopre che probabilmente in futuro verranno aggiunte nuove sottoclassi e il mio codice esistente dovrà gestirle con garbo. La HashMap sulla classe non funzionerà in questo caso perché la classe non verrà trovata. Una catena di istruzioni if, che inizia con la più specifica e termina con la più generale, è probabilmente la migliore dopo tutto:
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)
per inserire collegamenti nei commenti.