Switch Case – Code Smell und Möglichkeiten zum Refactoring

Switch Case Statements sollten nahezu immer als Code Smell gesehen werden. Das möchte ich hier kurz beleuchte. Zuerst folgt ein kleines Snippet, welches ein typisches Switch Case Statement zeigen soll.

Die Preise verschiedener Produktklassen sollen unterschiedlich reduziert werden.

Funktioniert. Ist aber nicht schön und kann Probleme machen, die man erst später erkennt, wenn die Codebase größer wird. Z.B. wird das Open/Closed Principle verletzt. Möchte man einen Typ hinzufügen, dann muss der bestehende Code erweitert werden. Hier ist bislang alles noch in einer Datei. In einem realen Umfeld sollte natürlich modularisiert werden. Dadurch würde die Switch Case Anweisung in einer Datei landen. Diese müsste erweitert werden, wenn neue Typen hinzukommen. Das widerspricht dem Closed des Open/Closed Principles (offen für Erweiterungen; verschlossen für Modifikationen). Praktisch gesehen sollte also für das Hinzufügen neuer Funktionalität die Notwendigkeit bestehen ein neues Element hinzuzufügen anstatt ein bestehendes Element (hier die Switch Case Anweisung) zu verändern.

Warum das so wichtig ist und was schief gehen kann, wenn man das nicht macht? Ganz einfach.

  1. Je mehr Unterscheidungen hinzu kommen, desto größer wird die Komplexität der Logik dieser Switch Case Anweisung (Anzahl Code-Zeilen)
  2. Einzelne Case Blöcke tendieren dazu, länger zu werden –> Gefahr der Code Duplication kommt auf.
  3. Das Testen solcher Switch Case Anweisungen wird schwieriger, je länger sie werden. Es können immer mehr Edge Cases hinzukommen

Wie kann man eine solch typische Switch Case Anweisung aber nun refaktorieren, um folgendes zu verbessern:

  • Lesbarkeit
  • Erweiterbarkeit
  • Vermeidung von Redundanz
  • Testbarkeit

Hier kann das Entwurfsmuster Strategie angewendet werden. Bei diesem Entwurfmuster können zur Laufzeit Algorithmen ausgetauscht werden, die zu einer Berechnung notwendig sind. Für jede Produktklasse im o.g. Beispiel würde also ein Algorithmus zur Strategie hinzugefügt. Das ganze würde dann in etwa so aussehen:

Das Beispiel zeigt sehr schön, wie vieles eigentlich ähnlich ist. Der Konstruktor des VoucherSystem Objekts bekommt lediglich ein Strategieobjekt anstatt eines type-Strings. Zudem fällt das Switch Case weg und die Algorithmen zur Berechnung verschieben sich in die jeweiligen Objekte der Strategie.

Einfach, oder? Zugegeben, es sind ein paar Zeilen mehr geworden für das Rahmenwerk. Das ist aber genau der Aufbau, der langfristig Komplexität reduziert.

KM

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie mehr darüber, wie Ihre Kommentardaten verarbeitet werden .