Skip to main content
Entwickler Themen
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

4.2. if-Sequenzen vermeiden

Wenn derselbe Wert eine Kette von Aktionen auslöst, wächst ein if/else if schnell zu unleserlichem und fehleranfälligem Code:

if (someVar == SOME_VALUE) {
  // ...
} else if (someVar == SOME_OTHER_VALUE) {
  // ...
} else if (someVar == ANOTHER_VALUE) {
  // ...
}

Eine kurze Treppe, bevor so eine Kette stehen bleibt.

1. Verteilermethoden vermeiden

Oft braucht es die zentrale Methode gar nicht. Statt in actionPerformed zu fragen, welcher Button gedrückt wurde, bekommt jedes Control seine eigene Methode:

meinButton.addActionListener(this::handleButtonAction);
anderes.addActionListener(e -> { /* konkrete Aktion */ });

Dasselbe Prinzip gilt für API-Handler oder Workflow-Schritte: die konkrete Funktion direkt zuordnen, statt später anhand eines Parameters zu verzweigen.

2. switch

Wenn wirklich ein Wert mehrere feste Fälle unterscheidet, ist switch klarer als eine if-Kette:

switch (someVar) {
  case SOME_VALUE:
    break;
  case SOME_OTHER_VALUE:
    break;
  default:
    throw new IllegalArgumentException("unbekannt: " + someVar);
}

Klassisches switch vergleicht einen Wert mit Konstanten (int, char, String, Enum). Ab Java 21 kann switch zusätzlich Typmuster. Komplexe Bereichs- oder Mehrvariablen-Bedingungen bleiben if.

3. Map plus funktionale Schnittstelle

Wenn Fälle zur Laufzeit wachsen oder aus Konfiguration kommen, trennt eine Map Schlüssel und Aktion:

@FunctionalInterface
interface MyFunctionalInterface {
  void doSomething();
}

Map<Integer, MyFunctionalInterface> myActions = new HashMap<>();
myActions.put(0, () -> System.out.println("0"));
myActions.put(1, () -> System.out.println("1"));

MyFunctionalInterface action = myActions.get(someVar);
if (action != null) {
  action.doSomething();
} else {
  throw new IllegalArgumentException("unbekannt: " + someVar);
}

Der Aufbau der Map kann selbst unübersichtlich werden. Fehlende Schlüssel brauchen eine bewusste Strategie. Für wenige feste Konstanten bleibt switch oft lesbarer; eine HashMap ist für übliche Fallzahlen kein Leistungsproblem.

4. Enum mit Verhalten

Wenn die Menge der Werte fest ist, gehört das Verhalten an das Enum – illegale int-Werte fallen dann weg:

@FunctionalInterface
interface MyFunctionalInterface {
  void doSomething();
}

public enum MyValues {
  SOME_VALUE(() -> System.out.println("SOME_VALUE")),
  SOME_OTHER_VALUE(() -> System.out.println("some other value"));

  private final MyFunctionalInterface action;

  MyValues(MyFunctionalInterface action) {
    this.action = action;
  }

  public void doAction() {
    action.doSomething();
  }
}

myVal.doAction();

Enums sind zur Compile-Zeit fest. Zu viel Logik im Enum verwischt die Zuständigkeit; dann sind Strategy- oder Command-Objekte die bessere nächste Stufe.

Weiterführende Muster

Wenn diese Ideen nicht reichen, dann gibt es einige Entwurfsmuster, die ggf. interessant sein könnten: Strategy, Command, Observer, Factory Method, Decorator. Die Wahl hängt davon ab, ob Algorithmen austauschbar, Aktionen speicherbar oder Zustandsänderungen beobachtbar sein sollen.