Was ist Clean Code?

Von 쉬었음.com

Clean Code ist Code, der nicht nur zum Kompilieren und Ausführen geschrieben wird, sondern so, dass andere Entwickler seine Absicht verstehen und ihn später sicher ändern, erweitern und überprüfen können. Es handelt sich nicht um ein Konzept, das durch einen einzigen strengen internationalen Standard oder Score definiert ist. Vielmehr ist es ein praktischer Begriff, der Qualitätsziele wie Lesbarkeit, Verständlichkeit, Wartbarkeit, Konsistenz und Änderungssicherheit umfasst. google.github.io

Zunächst ist es leicht, darunter einfach „gut aussehenden Code“ zu verstehen. In der Praxis sind jedoch die Momente nach dem ersten Schreiben des Codes entscheidend: wenn eine Funktion korrigiert, ein Fehler gesucht, eine Anforderung ergänzt oder die Arbeit eines Kollegen geprüft wird. Bei Clean Code geht es stärker darum, in diesen Momenten den Zeitaufwand und die Wahrscheinlichkeit von Fehlern zu verringern. Entscheidend ist daher nicht, bestimmte Syntaxtechniken auswendig zu lernen, sondern zu überlegen, was ein Leser wissen muss und wo sich eine Änderung auswirkt.

Was bedeutet Clean Code genau?

Software ist kein Dokument, das einmal geschrieben und dann abgeschlossen wird. Bestehender Code wird erneut gelesen, wenn ein Bestellstatus ergänzt, eine Preisregel geändert oder ein Fehler untersucht wird. Der Leser kann der ursprüngliche Entwickler sein, ist aber häufig ein anderes Teammitglied oder man selbst in der Zukunft. Clean Code bezeichnet einen Zustand, in dem dieser Leser die Rolle des Codes, seine Eingaben und Ausgaben, wichtige Bedingungen und wahrscheinliche Änderungsstellen relativ schnell verstehen kann.

„Clean“ ist hier nicht nur ein ästhetisches Urteil. Selbst gut formatierter Code ist beispielsweise riskant zu ändern, wenn seine Namen mehrdeutig sind, mehrere Verantwortlichkeiten in einer Funktion vermischt werden und es keine Möglichkeit zur Überprüfung gibt. Umgekehrt kann Code aus Wartungssicht besser sein, wenn seine Rolle klar ist, er den Teamkonventionen entspricht und Tests vorhanden sind, die Änderungen bestätigen können – auch wenn er keinen besonders auffälligen Stil verwendet. Code Reviews prüfen nicht nur den Stil, sondern auch Design, funktionale Korrektheit, Komplexität, Tests und Dokumentation. google.github.io

Der Begriff Clean Code wurde durch Robert C. Martins Buch Clean Code aus dem Jahr 2008 weithin bekannt. Die Empfehlungen des Buches stehen jedoch im Kontext bestimmter Sprachen und objektorientierter Entwicklungspraktiken. Statt ein Buch oder eine bekannte Regel unverändert auf jede Sprache und jede Programmgröße anzuwenden, ist es angemessener zu beurteilen, ob sie ein Problem in der aktuellen Codebasis und im aktuellen Team löst. www.informit.com

Warum reicht Code, der funktioniert, nicht aus?

Das gewünschte Ergebnis für die aktuellen Eingaben zu liefern, ist die grundlegendste Anforderung an ein Programm. Doch auch korrekte Funktionalität lässt sich langfristig schwer verwalten, wenn sie bei der nächsten Änderung leicht beschädigt wird. Eine lange Funktion kann beispielsweise Rabattberechnung, Berechtigungsprüfungen, Darstellung und Datenspeicherung enthalten. Sie mag jetzt funktionieren, aber jemand, der nur die Rabattregel ändern will, beeinflusst dann mit höherer Wahrscheinlichkeit auch die Berechtigungsbehandlung oder die Speicherreihenfolge.

Schwer lesbarer Code bedeutet nicht nur, dass das Lesen länger dauert. Ohne Sicherheit über die Absicht können Entwickler ähnliche Logik kopieren, einen größeren Bereich als nötig ändern oder Regeln neu erstellen, die bereits existieren. Auch Reviewer können die Auswirkungen einer Änderung schwer beurteilen. Wartbarkeit ist die Eigenschaft, künftige Änderungen nicht zu blockieren, und Clean Code konzentriert sich darauf, diese Wartbarkeit zu verbessern.

Dennoch kann niemand alle künftigen Änderungskosten im Voraus beseitigen. Wenn Anforderungen selbst komplex sind oder externe Systeme starke Einschränkungen auferlegen, wird auch der Code bis zu einem gewissen Grad komplex sein. Das bessere Ziel besteht nicht darin, die Realität als einfach darzustellen, sondern vermeidbare von unvermeidbarer Komplexität zu unterscheiden. Ist Komplexität notwendig, sollte ihr Grund durch Struktur, Namen, Tests und Dokumentation sichtbar gemacht werden.

Wie machen gute Namen die Absicht des Codes sichtbar?

Namen sind die Information, auf die Leser beim ersten Verstehen von Code am häufigsten stoßen. Allgemeine Namen wie x, data, process und flag mögen ihrem Autor vertraut sein, sagen anderen aber nicht, was sie darstellen. Namen wie expiredCouponCount, isEligibleForRefund und calculateShippingFee vermitteln dagegen den Zweck eines Werts oder einer Operation relativ direkt. Aussagekräftige Namen sind außerdem eine Möglichkeit, Informationen, die sonst in Kommentaren erklärt werden müssten, in den Code selbst zu verlagern. google.github.io

Gute Benennung ist eine Frage der Genauigkeit, nicht der Länge. Ein weithin verständliches Konzept in einem kleinen Gültigkeitsbereich kann einen kurzen Namen haben, während ein Wert in einem breiteren Gültigkeitsbereich mehr Kontext benötigen kann. Der Schleifenindex i kann beispielsweise innerhalb einer sehr kurzen Schleife verständlich sein. Heißt jedoch ein Rückgabewert einer Funktion oder ein Objektfeld nur result, ist schwer erkennbar, ob er Erfolg, einen Betrag oder ein Abfrageergebnis darstellt.

Auch die Unterscheidung zwischen Verben und Substantiven ist hilfreich. Das Lesen folgt häufig natürlich, wenn Funktionen verbbasierte Namen verwenden, die offenlegen, was sie tun, während Werte und Objekte substantivbasierte Namen verwenden, die offenlegen, was sie sind. sendReceipt() ist eine Aktion, während receiptEmail Daten sind. Einen Namen zu verlängern, beseitigt jedoch nicht automatisch Mehrdeutigkeit. handleUserData ist länger, aber es bleibt unklar, was damit verarbeitet wird.

// Example with unclear intent
if (a) {
  doIt(b);
}

// Example where the purpose of the condition and action is visible
if (isPaymentApproved) {
  sendOrderConfirmation(order);
}

Die Namen im zweiten Beispiel sollten dennoch an den tatsächlichen Kontext angepasst werden. Der Punkt ist, dass Leser die wichtige Entscheidung verstehen sollen, ohne weit entfernt nach den Definitionen von a und b suchen zu müssen. Gegenüber einer Struktur, in der Kommentare wiederholen, was Namen bereits erklären, birgt eine Benennung und Zusammensetzung, durch die sich der Code selbst erklärt, ein geringeres Risiko, dass die Erklärung nach einer Änderung veraltet.

Wie stark sollten Funktionen und Strukturen aufgeteilt werden?

Wenn eine Funktion oder ein Modul zu viele Aufgaben erfüllt, müssen Leser mehrere Regeln gleichzeitig im Kopf behalten. Sind Eingabevalidierung, Berechnung, externe Aufrufe, Fehlerbehandlung und Ergebnisformatierung in einem Block vermischt, kann die Änderung eines Teils das Verständnis des gesamten Ablaufs erfordern. Die Trennung zusammengehöriger Schritte in benannte Einheiten kann den Ablauf auf hoher Ebene leichter lesbar machen.

Ein Auftragsbestätigungsprozess könnte beispielsweise durch Schritte wie validateOrder, calculateTotal, reserveInventory und createPayment dargestellt werden, die den Geschäftsablauf ausdrücken. Der Zweck der Trennung besteht nicht darin, die Anzahl der Funktionen zu erhöhen, sondern die Verantwortung und Reihenfolge jedes Schritts leichter lesbar zu machen. Wenn eine extrahierte Funktion nur aus einer Zeile besteht und ihr Name weniger klar ist als der ursprüngliche Ausdruck, lässt sich kaum schlussfolgern, dass die Extraktion das Verständnis verbessert.

Übermäßige Aufteilung schafft das gegenteilige Problem. Leser müssen möglicherweise zwischen vielen Dateien und dünnen Funktionen wechseln, um eine Aktion zu verstehen. Abstraktionen wie Interfaces oder Typen haben den Vorteil, Implementierungsdetails zu verbergen, können aber auch benötigten Kontext verdecken. Abstraktion sollte eingesetzt werden, wenn sie einen klaren Nutzen bietet, und nicht unter der Annahme, dass „mehr Abstraktion immer besseres Design bedeutet“. google.github.io

Ob eine Aufteilung sinnvoll ist, lässt sich daher anhand solcher Fragen beurteilen:

  • Hat dieser Teil eine Rolle, die sich unabhängig erklären lässt?
  • Erklärt sein Name die Absicht besser als das Lesen des internen Codes?
  • Wird dieselbe Regel an mehreren Stellen wiederholt, sodass es einen Grund gibt, sie an einer Stelle zusammenzuführen?
  • Entsteht dadurch eine Grenze, an der bei einer Änderung nur dieser Teil untersucht werden muss?
  • Wird der Gesamtfluss nach der Trennung durch das Nachverfolgen von Aufrufen stattdessen unklarer?

Diese Fragen liefern nicht automatisch eine Antwort. Sie lenken die Aufmerksamkeit jedoch auf die tatsächlichen Kosten, die Leser beim Verstehen des Codes haben, statt auf oberflächliche Regeln wie „kurze Funktionen“.

Bedeutet Einfachheit dasselbe wie weniger Funktionen?

Im Kontext von Clean Code bedeutet Einfachheit nicht, benötigte Funktionalität aufzugeben. Sie bedeutet eher, unnötige Strukturen, ungenutzte Erweiterungspunkte und schwer verständliche Umwege zu vermeiden, die von aktuellen Anforderungen nicht verlangt werden. Wird allein aufgrund von Vermutungen über künftige Bedürfnisse verallgemeinert, müssen aktuelle Leser Fälle verstehen, die noch gar nicht existieren.

Der vorzeitige Aufbau eines mehrschichtigen Plug-in-Systems für eine kleine Funktion mit nur einer Zahlungsmethode kann beispielsweise Raum für spätere Erweiterungen schaffen. Er erhöht aber auch unmittelbar die Codepfade, Konfiguration und Kombinationen, die getestet werden müssen. Wenn das Hinzufügen weiterer Zahlungsmethoden dagegen bereits bestätigt ist und deren Regeln erheblich voneinander abweichen, kann eine gemeinsame Grenze künftige Änderungen verringern. Keine der beiden Entscheidungen ist im Voraus immer besser.

Einfachheit bedeutet auch nicht „möglichst wenige Codezeilen“. Mehrere Bedingungen und Transformationen in einer Zeile zu verdichten, kann dem Autor elegant erscheinen, doch die Person, die sie ändern muss, muss Prioritäten und Ausnahmen interpretieren. Umgekehrt können passend benannte Zwischenwerte und getrennte Bedingungen die Zeilenzahl erhöhen und zugleich den Denkprozess vereinfachen. Leitlinien für Code Reviews betonen ebenfalls, dass künftige Entwickler den Code lesen, verstehen und ändern können sollten. google.github.io

In der Praxis ist es sinnvoll, zwei Arten von Einfachheit gemeinsam zu betrachten. Die erste ist die Einfachheit der Implementierung selbst: ob es wenige unnötige Zustände, Verzweigungen, Abhängigkeiten und Duplizierungen gibt. Die zweite ist die Einfachheit der Nutzung und Änderung: ob Aufrufer sie leicht korrekt verwenden können und ob bei Regeländerungen klar ist, wo angepasst werden muss. Eine Entscheidung, die die externe Nutzung vereinfacht, kann manchmal besser sein, selbst wenn die Interna etwas komplexer sind.

Warum ist ein konsistenter Stil notwendig, und warum reicht er nicht aus?

Wenn Einrückungen, Zeilenumbrüche, Dateiorganisation und Benennungskonventionen alle variieren, müssen Leser das Format jedes Mal neu interpretieren. Ein vom Team vereinbarter und konsequent verwendeter Stil kann die Aufmerksamkeit reduzieren, die für oberflächliche Unterschiede im Code aufgewendet wird. Werkzeuge, die Regeln mechanisch prüfen, etwa automatische Formatter und Linter, können für diese wiederkehrende Arbeit besonders nützlich sein.

Die bloße Einhaltung eines Stils macht Code jedoch nicht clean. Selbst wenn jeder Name derselben Konvention folgt, können Rollen weiterhin mehrdeutig sein; selbst wenn Zeilenlängen stimmen, kann das Design immer noch zu stark verwoben sein. Die Qualitätsprüfung von Code vertritt die Ansicht, dass neben dem Stil auch Design, Funktionalität, Komplexität, Tests und Dokumentation berücksichtigt werden sollten. google.github.io

Bei der Anwendung von Stilregeln ist es in der Regel praktisch, die bestehenden Konventionen des Teams zu respektieren. Eine bevorzugte Schreibweise nur in einer neuen Datei einzuführen, mag geringfügig wirken, kann aber die Konsistenz im gesamten Projekt schwächen. Umgekehrt kann eine bestehende Konvention besprochen und geändert werden, wenn eine Verbesserung die Klarheit deutlich erhöht. Entscheidend ist nicht, darüber zu konkurrieren, welche Regel eleganter ist, sondern ob das Team den Code einheitlich lesen und ändern kann.

Bei Code Reviews muss außerdem zwischen geringfügigen Geschmacksunterschieden und Problemen unterschieden werden, die die Wartbarkeit beeinflussen. In jeder Änderung Perfektion zu verlangen, kann die Verbesserung selbst verlangsamen. Verbessert eine Änderung Wartbarkeit, Lesbarkeit und Verständlichkeit insgesamt, kann es realistischer sein, sie schrittweise zu akzeptieren. google.github.io

Welche Beziehung besteht zwischen Tests und Clean Code?

Tests sind ausführbare Mittel zur Überprüfung des Verhaltens, das der Code zusichert. Eine Zusicherung ist hier beobachtbares Verhalten wie „nur gültige Bestellungen werden bezahlt“, „eine bereits stornierte Bestellung wird nicht erneut storniert“ oder „der angegebene Betrag wird abgezogen, wenn Rabattbedingungen erfüllt sind“. Tests bieten eine Grundlage, um zu prüfen, ob kritisches Verhalten nach einer Änderung beschädigt wurde.

Wird Clean Code lediglich als gut aussehender Code betrachtet, können Tests davon getrennt erscheinen. Unter einer Definition, die sichere Änderungen einschließt, sind Tests jedoch zentral. Bei einer strukturellen Bereinigung muss sich bestätigen lassen, dass das externe Verhalten erhalten blieb; und beim Hinzufügen einer neuen Regel muss geprüft werden, dass alte Regeln nicht versehentlich verletzt wurden. Wartbarer Code sollte Tests enthalten, die Kernlogik und zugesichertes Verhalten überprüfen und helfen, die Ursache von Fehlern zu identifizieren. google.github.io

Viele Tests allein garantieren keine Qualität. Tests, die zu eng an eine geringfügige interne Reihenfolge gekoppelt sind, können selbst legitime strukturelle Verbesserungen erschweren. Umgekehrt tragen Tests, die wichtige Grenzbedingungen und Geschäftsregeln auslassen, möglicherweise nicht ausreichend zur Änderungssicherheit bei, selbst wenn es viele davon gibt. Auch Testnamen und die Arrange-Act-Assert-Struktur sollten klar formuliert sein, damit Leser wissen, was gewährleistet wird.

Berechnet eine Logik beispielsweise einen Zeitraum für die Erstattungsberechtigung, ist es aussagekräftiger, die Grenzen der tatsächlichen Regel zu testen – etwa den Stichtag selbst, den Zeitpunkt unmittelbar nach dem Stichtag und fehlende Eingaben –, statt nur gewöhnliche Daten zu prüfen. Welche Fälle getestet werden sollten, hängt von Produktanforderungen und Risiken ab. Entscheidend ist, dass Tests nicht nur vermitteln, dass „Code vorhanden ist“, sondern „welches Verhalten weiterhin erhalten bleiben muss“.

Wann sind Kommentare und Dokumentation notwendig?

Kommentare sind nicht schlecht. Sie sind besonders wertvoll, wenn sie Hintergrund vermitteln, den Code nur schwer ausdrücken kann. Namen allein können beispielsweise einen Workaround für anormales Verhalten eines externen Dienstes, gesetzliche oder vertragliche Einschränkungen, eine auf Performancemessungen beruhende Entscheidung oder den Grund für temporären Kompatibilitätscode, der nach einem bestimmten Datum entfernt wird, möglicherweise nicht angemessen vermitteln. Diese Informationen helfen künftigen Wartenden zu verstehen, warum sie ihn nicht durch einen einfacheren Ansatz ersetzen sollten. google.github.io

Kommentare, die lediglich übersetzen, was der Code bereits sagt, können mit der Zeit vom Code abweichen. Ein Kommentar wie „Zähler um 1 erhöhen“ neben count = count + 1 fügt keine neuen Informationen hinzu. In diesem Fall kann ein besserer Name oder eine direktere Struktur Vorrang haben. Je länger Kommentare werden, desto mehr lohnt es sich zu prüfen, ob sie auf eine unklare Codeabsicht hinweisen.

Auch der geeignete Ort für Dokumentation kann unterschiedlich sein. Ein lokaler Grund innerhalb einer Funktion passt möglicherweise zu einem Kommentar in der Nähe. Nutzungsregeln, Konfigurationsmethoden und Kompatibilitätsbedingungen, die über mehrere Module geteilt werden, lassen sich möglicherweise leichter in separater Dokumentation oder Schnittstellenbeschreibungen finden. Unabhängig vom Ort ist es wichtig, Lesern den Kontext für Entscheidungen zu geben und ihn bei Codeänderungen gemeinsam zu aktualisieren.

Wie unterscheiden sich Clean Code, Refactoring und Coding Style?

Diese drei Begriffe werden oft zusammen genannt, haben aber unterschiedliche Rollen. Clean Code ist ein Qualitätszustand oder eine Perspektive mit dem Ziel, Code leicht verständlich und änderbar zu machen. Refactoring ist die Tätigkeit, die interne Struktur zu verbessern und dabei das extern beobachtbare Verhalten zu bewahren. Coding Style ist eine Konvention für die Ausdrucksform von Code, beispielsweise Einrückung, Namensnotation und Leerzeichen.

KategorieKernfrageUmfang
Clean CodeKann dieser Code verstanden und sicher geändert werden?Namen, Struktur, Komplexität, Tests, Dokumentation, Konsistenz
RefactoringWie kann die Struktur unter Beibehaltung des Verhaltens verbessert werden?Eine Tätigkeit zur strukturellen Verbesserung
Coding StyleIn welchem Format drückt das Team Code aus?Konventionen für Schreibweise und Formatierung

Refactoring ist eine Möglichkeit, Clean Code zu schaffen oder zu erhalten. Duplizierte Preisberechnungen können beispielsweise an einer Stelle zusammengeführt, mehrdeutige Namen geändert und Bedingungen in leichter verständliche Einheiten gegliedert werden. Strukturelle Änderungen, bei denen nicht bestätigt wird, dass das Verhalten erhalten bleibt, können jedoch riskant sein; deshalb sind Tests und Reviews wichtig.

Stil reduziert Reibung bei der Zusammenarbeit, löst aber nicht automatisch Designprobleme. Umgekehrt ist klarer Code mit einer funktionierenden Struktur nicht automatisch schlecht, nur weil sein Stil geringfügig abweicht. Dieses Verständnis verringert den Fehler, Formatierungsprobleme und echte Wartungsrisiken in Reviews gleich zu gewichten. google.github.io

Was sollte bei Performance- und Sicherheitsanforderungen Vorrang haben?

Die Betonung von Einfachheit und Klarheit bei Clean Code bedeutet nicht, Performance, Sicherheit, Kompatibilität oder Betriebszuverlässigkeit zu opfern. Ein für die Performance erforderlicher Cache, für die Sicherheit notwendige Validierungsschritte oder Kompatibilitätsbehandlung für ein altes externes System können Code beispielsweise komplexer machen. Beruht diese Komplexität auf tatsächlichen Anforderungen und Messergebnissen, kann sie angemessener sein als eine Alternative, die nur einfacher aussieht.

Die wichtige Haltung in dieser Situation ist, Komplexität nicht zu verstecken. Einschränkungen, zu garantierendes Verhalten und Gründe, eine herkömmliche Implementierung nicht zu verwenden, können durch Namen, Struktur, Tests und notwendige Kommentare sichtbar gemacht werden. Das Prinzip, technische Fakten und Daten gegenüber persönlichen Vorlieben zu priorisieren, gilt auch für diese Entscheidungen. google.github.io

Wenn beispielsweise eine leicht lesbare Implementierung die Antwortzeitvorgaben in der tatsächlichen Produktionsumgebung nicht erfüllt, gibt es einen Grund, eine komplexere Implementierung zu wählen. Es ist jedoch ebenso nicht wünschenswert, jeden Code nur unter der Annahme komplex zu machen, dies sei „für die Performance“. Nach Messung des Problems und Bestätigung der Anforderungen sollten sowohl Kosten als auch Nutzen der Komplexität verglichen werden.

Dasselbe gilt für die Sicherheit. Schritte wie Eingabevalidierung, Autorisierungsprüfungen und Fehlerbehandlung können den Codefluss verlängern. Das bedeutet nicht, dass sie weggelassen werden können, um den Code kürzer zu machen. Eine gute Struktur platziert diese notwendigen Schritte so, dass sie leicht erkennbar sind, und verhindert, dass sensible Regeln willkürlich über die gesamte Codebasis verstreut werden.

Welche verbreiteten Missverständnisse gibt es über Clean Code?

Das erste Missverständnis lautet: „Kürzer ist immer besser.“ Kurze Funktionen und knappe Ausdrücke können helfen, aber die Zeilenzahl ist nicht das Kriterium. Übermäßige Aufteilung und Abstraktion können Aufrufpfade verlängern und Kontext verbergen. Statt zu fragen, ob der Code kürzer geworden ist, sollte gefragt werden, ob Leser den Hauptfluss und seine Gründe leichter verstehen können. google.github.io

Das zweite Missverständnis lautet: „Weniger Kommentare sind immer besser.“ Die Idee, Inhalte, die der Code selbst durch Namen und Struktur erklären kann, dort auszudrücken, bedeutet nicht, nützliche Hintergrundinformationen zu entfernen. Insbesondere Gründe für Entscheidungen und externe Einschränkungen müssen möglicherweise in Kommentaren oder Dokumentation erhalten bleiben. Gute Kommentare wiederholen den Code nicht; sie liefern Kontext, der allein aus dem Code schwer zu erkennen ist. google.github.io

Das dritte Missverständnis lautet: „Code ist nur dann gut, wenn er jede Regel befolgt.“ Empfehlungen sind Werkzeuge für Urteile, kein Gesetzbuch, das auf jede Situation zutrifft. Prioritäten variieren je nach Spracheigenschaften, bestehenden Projektkonventionen, Performance- und Sicherheitsanforderungen sowie Teamerfahrung. Wichtiger ist zu prüfen, ob die Anwendung einer Regel den Code tatsächlich klarer macht.

Das vierte Missverständnis lautet: „Das Design muss von Anfang an perfekt sein.“ Anforderungen ändern sich, und manche Informationen sind anfangs nicht bekannt. Statt Änderungen zu verzögern, indem ausschließlich Perfektion angestrebt wird, ist es realistischer, weiterhin kleine Verbesserungen vorzunehmen, die das aktuelle System insgesamt leichter lesbar und wartbar machen. google.github.io

Wie lässt sich Clean Code in der Praxis beurteilen?

Es ist schwierig, Clean Code allein mit einer absoluten Checkliste zu beurteilen, aber bei einer Änderung lassen sich mehrere Fragen stellen. Zunächst sollte geprüft werden, ob jemand, der den Code zum ersten Mal sieht, seinen Hauptzweck erklären kann. Als Nächstes sollte bei der Änderung einer Regel kontrolliert werden, ob die anzupassende Stelle relativ klar ist oder ob auch nicht zusammenhängende Bereiche geändert werden müssen. Schließlich sollte bestätigt werden, ob Tests oder Review-Verfahren existieren, um das Kernverhalten nach der Änderung zu überprüfen.

Hier sind praktische Fragen für das Schreiben oder Reviewen einer Funktion:

  • Lässt sich die Rolle eines Werts, einer Funktion oder eines Moduls grob allein aus seinem Namen verstehen?
  • Vermischt eine Funktion unnötig unterschiedliche Geschäftsregeln oder externe Operationen?
  • Wird dieselbe wichtige Regel an mehreren Stellen kopiert?
  • Entspricht sie auf natürliche Weise den Teamkonventionen für Benennung, Formatierung und Dateiorganisation?
  • Wurden Gründe für Entscheidungen oder Einschränkungen, die der Code nicht ausdrücken kann, bei Bedarf festgehalten?
  • Gibt es eine Möglichkeit, Kernverhalten und riskante Grenzbedingungen zu überprüfen?
  • Wurden bei der Vereinfachung Anforderungen an Performance, Sicherheit oder Kompatibilität übersehen?
  • Verringern die Abstraktion oder Trennung tatsächlich die Kosten des Verständnisses, oder verlängern sie nur den Pfad, dem Leser folgen müssen?

Nicht alle diese Fragen müssen sofort beantwortet werden. Der Versuch, in einer kleinen Änderung jedes Designproblem zu lösen, kann ein Review zum Stillstand bringen. Es ist praktisch, zuerst Probleme mit hoher Auswirkung zu beheben und den Rest in späteren Änderungen in eine bessere Richtung zu entwickeln. Das Ziel eines Code Reviews kann auch die kontinuierliche Verbesserung von Wartbarkeit, Lesbarkeit und Verständlichkeit des Systems sein, statt perfekten Code zu erzeugen. google.github.io

Fazit: Clean Code ist Qualität für Änderungen, kein festes Format

Clean Code bedeutet nicht nur eine Liste von Regeln aus einem bestimmten Buch oder ordentliche Formatierung. Es ist eine Qualitätsperspektive, die die Absicht des Codes durch Namen und Struktur sichtbar macht, unnötige Komplexität verringert, ein konsistentes Lesen im Team ermöglicht und die Überprüfung des Verhaltens nach Änderungen erlaubt. Kommentare vermitteln Hintergrund, Tests unterstützen die Änderungssicherheit, und Abstraktionen werden eingesetzt, wenn sie Verständnis und Änderungen tatsächlich erleichtern.

Die Form guten Codes kann von Projekt zu Projekt unterschiedlich sein. Entscheidend ist nicht, ob er kurz aussieht oder einer berühmten Regel folgt, sondern ob der nächste Entwickler ihn unter den aktuellen Anforderungen und Einschränkungen korrekt verstehen und ändern kann. Kleine Namen, Bedingungen, Tests und Strukturen aus dieser Perspektive kontinuierlich zu verbessern, ist der praktische Ausgangspunkt von Clean Code. google.github.iogoogle.github.io

Häufig gestellte Fragen

Kann Clean Code mit einer festen Formel oder Punktzahl bewertet werden?

Nein. Clean Code ist weder ein einzelner internationaler Standard noch eine Messformel, sondern eine praktische Qualitätsperspektive, die Verständlichkeit, Wartbarkeit, Konsistenz und die Sicherheit von Änderungen verbessern soll. Welche Entscheidungen richtig sind, kann je nach Programmiersprache, Team und betrieblichen Rahmenbedingungen des Projekts variieren.

Ist Code immer clean, wenn er kurz ist?

Nein. Kurzer Code kann Absichten manchmal klarer machen, aber übermäßige Verdichtung, Aufteilung oder Abstraktion kann Kontext und Ausführungsfluss verbergen und den Code schwerer lesbar machen. Entscheidend ist nicht die Zeilenzahl, sondern ob Leser die Absicht verstehen und den Code sicher ändern können.

Bedeutet eine große Anzahl von Kommentaren, dass Code hochwertig ist?

Nicht unbedingt. Verhalten, das sich durch Namen und Struktur ausdrücken lässt, wird oft besser durch den Code selbst erklärt. Kommentare sind jedoch wertvoll für Hintergründe, die sich allein aus dem Code nur schwer ableiten lassen, etwa Gründe für eine Entscheidung, externe Einschränkungen oder unvermeidbare Ausnahmen.

Sind Clean Code und Refactoring dasselbe?

Nein. Clean Code bezeichnet einen Zustand, in dem Code verständlich und leicht wartbar ist, während Refactoring die Tätigkeit ist, die interne Struktur unter Beibehaltung des extern beobachtbaren Verhaltens zu verbessern. Refactoring kann daher ein Weg zu saubererem Code sein.

Muss man auf Clean-Code-Prinzipien verzichten, wenn für die Performance komplexer Code erforderlich ist?

Nein. Komplexität, die tatsächlich aufgrund von Performance, Sicherheit, Kompatibilität oder betrieblichen Bedingungen erforderlich ist, kann notwendig sein. Statt Anforderungen zu ignorieren, weil ein einfacherer Ansatz sauberer wirkt, sollte Komplexität anhand von Messungen und technischen Erkenntnissen gewählt und ihr Grund sichtbar gemacht werden.