Die versteckte Komplexität
Man kann nicht ernsthaft von Clean Code sprechen, ohne die saubere Behandlung von Fehlersituationen zu berücksichtigen. Fehlerbehandlung stellt eine eigenständige Verantwortlichkeit dar, die vom fachlichen Code getrennt werden sollte. Das Ziel bleibt, wie bei allen Clean-Code-Prinzipien, die klare Trennung: Domain-Code sollte auf den ersten Blick erkennbar sein, ohne von try-catch-Blöcken oder if-Konditionen zur Prüfung von Fehlercodes überlagert zu werden.
Die Basis guter Fehlerbehandlung
Try-catch-finally war ein erster wichtiger Schritt zur Trennung von Verantwortlichkeiten: Im try-Block steht der fachliche "Happy Path", während im catch-Block die Behandlung der Ausnahme erfolgt. Wenn wir eigene Exceptions definieren, sollten wir diese Grundsätze beachten:
Unchecked Exceptions bevorzugen: Sie vermeiden Boilerplate-Code und führen zu klareren Schnittstellen
Technische vs. fachliche Exceptions: Unterscheide klar zwischen technischen Fehlern und fachlichen Ausnahmen
Kontextinformationen liefern: Exceptions sollten aussagekräftige Informationen über den Fehlerkontext enthalten
Exception-Design aus Clientsicht: Gestalte Exceptions so, wie sie von den Nutzern deiner API benötigt werden
Von den gängigen Programmiersprachen ist Java praktisch die einzige, die checked Exceptions kennt – ein Konzept, das mittlerweile als problematisch gilt und hier nicht weiter ausgeführt werden muss.
Null-Werte vermeiden
Zwei weitere essenzielle Aspekte der Clean-Code-Fehlerbehandlung:
Keine null-Werte zurückgeben: Sie zwingen den Aufrufer zu zusätzlichen Prüfungen
Keine null-Werte als Methodenargumente akzeptieren: Sie machen das Verhalten von Methoden unvorhersehbar
Diese Regeln mögen trivial erscheinen, doch mit zunehmender Erfahrung erkennt man ihre Bedeutung – ganz im Sinne der bekannten Maximen "Code is a liability, not an asset" und "the best code is no code at all" von Jeff Atwood. Warum sind null-Werte als Methodenargumente problematisch? Sie erfordern vom Leser des Codes, das Verhalten der Methode in diesem Spezialfall zu verstehen und zu berücksichtigen.
Objektorientierte Lösungsansätze
In einer objektorientierten Programmiersprache lassen sich viele Fehlerbehandlungsszenarien elegant lösen oder sogar vermeiden. Besonders das Special Case Pattern und das Null Object Pattern bieten hier saubere Alternativen.
Strukturierte Fehlerbehandlung
Das Compose Method Pattern eignet sich hervorragend für eine strukturierte Fehlerbehandlung. Mein typischer Ansatz sieht wie folgt aus. Diese Methode funktioniert übrigens auch ausgezeichnet in Sprachen ohne Exception-Konzept wie Go.