Vermeiden von instanceof in Java

Das Einhalten einer Kette von "Instanzen" -Operationen wird als "Codegeruch" betrachtet. Die Standardantwort lautet "Verwende Polymorphismus". Wie würde ich das in diesem Fall machen?

Es gibt eine Reihe von Unterklassen einer Basisklasse. Keiner von ihnen steht unter meiner Kontrolle. Eine analoge Situation wäre mit den Java-Klassen Integer, Double, BigDecimal usw.

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);}

Ich habe die Kontrolle über NumberStuff und so weiter.

Ich möchte nicht viele Codezeilen verwenden, wo ein paar Zeilen ausreichen würden. (Manchmal erstelle ich eine HashMap-Zuordnung von Integer.class zu einer Instanz von IntegerStuff, BigDecimal.class zu einer Instanz von BigDecimalStuff usw.)

Ich hätte gerne so etwas Einfaches wie dieses:

public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }

Aber Java funktioniert einfach nicht so.

Ich möchte beim Formatieren statische Methoden verwenden. Die Dinge, die ich formatiere, sind zusammengesetzt, wobei ein Thing1 ein Array Thing2s und ein Thing2 ein Array Thing1s enthalten kann. Ich hatte ein Problem, als ich meine Formatierer wie folgt implementierte:

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);
  }
}

Ja, ich kenne die HashMap und ein bisschen mehr Code kann das auch beheben. Aber die "Instanz von" scheint im Vergleich so lesbar und wartbar zu sein. Gibt es etwas Einfaches, das aber nicht stinkt?

Hinweis hinzugefügt am 10.05.2010:

Es stellt sich heraus, dass wahrscheinlich in Zukunft neue Unterklassen hinzugefügt werden und mein vorhandener Code sie ordnungsgemäß handhaben muss. Die HashMap-Klasse funktioniert in diesem Fall nicht, da die Klasse nicht gefunden wird. Eine Kette von if-Anweisungen, beginnend mit den spezifischsten und endend mit den allgemeinsten, ist wahrscheinlich die beste:

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
}

Antworten auf die Frage(16)

Ihre Antwort auf die Frage