In letzter Zeit habe ich in dem Unternehmen, in dem ich derzeit arbeite, viel Code refaktoriert. Eines der häufigsten Probleme, auf die ich gestoßen bin, sind tief verschachtelte if/else/else if-Anweisungen. Sie neigen dazu, wie ein großer, verwickelter Baum zu wachsen. Das Problem ist, dass diese Strukturen schwer zu lesen und schwer nachzuvollziehen sind und oft doppelte Überprüfungen enthalten, wenn sie nicht sorgfältig verwaltet werden.

In diesem Tutorial zeige ich Ihnen einige praktische Möglichkeiten, diese Art von Code zu refaktorieren und ihn lesbarer und wartbarer zu machen.

function getDiscount(user) {
  if (user) {
    if (user.isMember) {
      if (user.purchaseHistory && user.purchaseHistory.length > 5) {
        return 0.2;
      } else {
        if (user.coupon) {
          if (user.coupon === 'VIP') {
            return 0.15;
          } else {
            return 0.1;
          }
        } else {
          return 0.05;
        }
      }
    } else {
      return 0;
    }
  } else {
    return 0;
  }
}

Tipp 1: Den “Happy Path” nehmen

Eine einfache, aber mächtige Technik, um die Verschachtelung zu reduzieren, ist es, zurückzukehren, sobald man genügend Informationen hat. Dies geschieht durch das Hinzufügen von Guard-Klauseln (Wächter) am Anfang der Funktion.

function getDiscount(user) {
  if (!user) return 0;                      // Wächter: kein Nutzer
  if (!user.isMember) return 0;             // Wächter: kein Mitglied

  if (user.purchaseHistory?.length > 5) return 0.2;
  if (user.coupon === 'VIP') return 0.15;
  if (user.coupon) return 0.1;

  return 0.05;
}

Diese Version ist einfacher zu verfolgen, da sich die Funktion wie eine lineare Abfolge von Regeln liest und nicht wie ein Baum verschachtelter Bedingungen. Jede Überprüfung ist isoliert, was den Code leichter verständlich und testbar macht.

Tipp 2: Es in ein Objekt auslagern

Eine weitere großartige Möglichkeit, lange bedingte oder Switch-Anweisungen zu ersetzen, ist die Verwendung einer Object Lookup Table (Nachschlagetabelle). Dieser Ansatz trennt die Logik (die Regeln selbst) vom Kontrollfluss.

const roleDiscount = {
  guest: 0,
  member: 0.05,
  vip: 0.15,
  staff: 0.25
};

function getRoleDiscount(role) {
  return roleDiscount[role] ?? 0; // O(1) Suche; Standard 0
}

Dieser Code kann lange Switch-Cases ersetzen, die so aussehen können:

function getRoleDiscountSwitch(role) {
  switch(role) {
    case 'guest': return 0;
    case 'member': return 0.05;
    case 'vip': return 0.15;
    case 'staff': return 0.25;
    default: return 0;
  }
}

Der Ansatz des Objekt-Mappings macht den Code nicht nur kürzer und aussagekräftiger, sondern bietet auch den zusätzlichen Vorteil einer O(1)-Komplexität beim Nachschlagen. Das Hinzufügen oder Ändern einer Rolle wird so einfach wie das Aktualisieren des Objekts, ohne die Funktionslogik anfassen zu müssen.

Fazit

Bedingungen sind eine der häufigsten Quellen von Komplexität im alltäglichen Code. Durch die Anwendung von Techniken wie Guard-Klauseln („dem Happy Path“) und Object Lookups können Sie tief verschachtelte Logik in saubere, testbare und erweiterbare Funktionen verwandeln.

Dies sind nur einige meiner bevorzugten Refactoring-Techniken. Und was ist mit Ihnen? Haben Sie andere Möglichkeiten, komplexe Bedingungen in JavaScript zu vereinfachen? Ich würde mich freuen, Ihre Ideen zu hören — teilen Sie sie gerne mit mir auf LinkedIn!

🌟 Bonus Tipp

Ich habe gerade etwas wirklich Nützliches zum Erlernen von Refactoring gefunden — 🎧 Five Lines of Code (Hörbuch). Es ist ehrlich gesagt der einfachste Weg, den ich kenne, um Refactoring zu verstehen, ohne sich überfordert zu fühlen.

Der coole Teil ist, dass Sie es mit der 30-tägigen Audible-Testversion von Amazon kostenlos erhalten können. Sie zahlen also keinen Cent, wenn Sie vor Ablauf der Testphase kündigen. Hier ist mein Affiliate-Link, wenn Sie es sich ansehen möchten: Five Lines of Code auf Audible — Ich kann eine kleine Provision erhalten, wenn Sie sich anmelden, ohne zusätzliche Kosten für Sie.