Wichtige Erkenntnisse
1. Sauberer Code ist lesbar, einfach und aussagekräftig
Sauberer Code sieht immer so aus, als wäre er von jemandem geschrieben worden, dem das Ergebnis wirklich wichtig ist.
Klarheit ist entscheidend. Sauberer Code zeichnet sich durch seine Lesbarkeit und Einfachheit aus. Er sollte für andere Programmierer leicht verständlich, änderbar und wartbar sein. Das bedeutet, klare und aussagekräftige Namen zu verwenden, Funktionen und Klassen klein und fokussiert zu halten sowie den Code logisch zu strukturieren.
Aussagekräftiger Code vermittelt Absicht. Sauberer Code sollte die Intention des Programmierers deutlich machen, ohne dass umfangreiche Kommentare nötig sind. Dies gelingt durch wohlüberlegte Namen, kleine Funktionen, die jeweils eine Aufgabe gut erfüllen, und eine klare Gesamtstruktur. Der Code selbst erzählt eine Geschichte, die es dem Leser leicht macht, der Logik und dem Zweck jeder Komponente zu folgen.
Kontinuierliche Verbesserung ist unerlässlich. Sauberen Code zu schreiben ist ein fortlaufender Prozess, der ständige Aufmerksamkeit und Refactoring erfordert. Programmierer sollten der Boy-Scout-Regel folgen: „Hinterlasse den Zeltplatz sauberer, als du ihn vorgefunden hast.“ Das bedeutet, bei jeder Änderung oder Erweiterung nach Möglichkeiten zu suchen, die Klarheit und Struktur des Codes auch in kleinen Schritten zu verbessern.
2. Bedeutungsvolle Namen erhöhen Klarheit und Wartbarkeit
Der Name einer Variablen, Funktion oder Klasse sollte alle wichtigen Fragen beantworten: Warum existiert sie, was tut sie und wie wird sie verwendet?
Wählen Sie beschreibende Namen. Namen sollten selbsterklärend sein und die Absicht hinter Variablen, Funktionen und Klassen offenbaren. Vermeiden Sie Ein-Buchstaben-Namen, Abkürzungen oder kryptische Codes, die erst mental entschlüsselt werden müssen.
Nutzen Sie einheitliche Namenskonventionen. Übernehmen und halten Sie sich an die Standardkonventionen Ihrer Programmiersprache und Ihres Teams. Dazu gehören:
- CamelCase für Klassennamen (z. B. CustomerOrder)
- camelCase für Variablen- und Funktionsnamen (z. B. totalAmount)
- GROSSBUCHSTABEN für Konstanten (z. B. MAX_SIZE)
Vermeiden Sie irreführende oder überflüssige Namen. Verwenden Sie keine Namen, die verwirren könnten. Zum Beispiel sollte „list“ nicht in einem Variablennamen auftauchen, wenn es sich nicht tatsächlich um eine Liste handelt. Auch redundante oder bedeutungslose Wörter wie „data“ oder „info“ sollten nur dann verwendet werden, wenn sie wirklich Mehrwert bieten.
3. Funktionen sollten klein sein, eine Aufgabe erfüllen und auf einer Abstraktionsebene arbeiten
Funktionen sollten eine Sache tun. Sie sollten sie gut tun. Und nur diese eine Sache.
Halten Sie Funktionen klein. Idealerweise sind Funktionen nicht länger als 20 Zeilen. Das erleichtert das Lesen, Verstehen und Warten. Kleine Funktionen lassen sich außerdem besser benennen, testen und wiederverwenden.
Prinzip der einzigen Verantwortung. Jede Funktion sollte eine klar definierte Aufgabe haben. Wenn eine Funktion mehrere Dinge tut, sollte sie in kleinere, fokussierte Funktionen aufgeteilt werden. Das erhöht die Lesbarkeit und macht den Code modularer und leichter änderbar.
Konsequente Abstraktionsebene. Innerhalb einer Funktion sollten alle Operationen auf derselben Abstraktionsebene stattfinden. Das Vermischen von hoch- und niedrigstufiger Logik erschwert das Verständnis und die Wartung. Nutzen Sie die Refactoring-Technik „Extract Method“, um unterschiedliche Abstraktionsebenen in separate Funktionen auszulagern.
4. Kommentare sollten minimal und wirklich notwendig sein
Der richtige Einsatz von Kommentaren kompensiert unser Versagen, uns im Code klar auszudrücken.
Code sollte selbsterklärend sein. Gut geschriebener Code mit klaren Namen und Struktur macht Kommentare oft überflüssig. Bevor Sie einen Kommentar hinzufügen, überlegen Sie, ob Sie den Code nicht so umgestalten können, dass seine Absicht klarer wird.
Setzen Sie Kommentare gezielt ein. Gute Kommentare erklären, warum etwas getan wird, nicht wie. Sie liefern Kontext oder Erläuterungen, die sich nicht allein im Code ausdrücken lassen. Nützliche Kommentare sind zum Beispiel:
- Rechtliche Hinweise (Copyright, Lizenz)
- Erläuterungen zu Absichten oder Algorithmen
- Warnungen vor Konsequenzen
- TODO-Kommentare (sparsam verwendet)
Vermeiden Sie überflüssige oder irreführende Kommentare. Schreiben Sie keine Kommentare, die nur wiederholen, was der Code ohnehin klar sagt. Veraltete oder falsche Kommentare sind schlimmer als keine, da sie Leser in die Irre führen können. Überprüfen und aktualisieren Sie Kommentare regelmäßig zusammen mit dem Code.
5. Eine saubere Formatierung verbessert die Lesbarkeit
Code-Formatierung ist Kommunikation – und Kommunikation ist die wichtigste Aufgabe eines professionellen Entwicklers.
Einheitlicher Stil ist wichtig. Legen Sie einen konsistenten Formatierungsstil für Ihren Code fest und halten Sie sich daran. Dazu gehören:
- Einrückungen
- Zeilenumbrüche
- Platzierung von Klammern
- Abstände um Operatoren und Schlüsselwörter
Vertikale Formatierung. Organisieren Sie den Code vertikal, um die Lesbarkeit zu erhöhen:
- Halten Sie zusammengehörige Konzepte nah beieinander
- Trennen Sie nicht zusammenhängende Konzepte
- Deklarieren Sie Variablen nahe ihrer Verwendung
- Platzieren Sie abhängige Funktionen nebeneinander
Horizontale Formatierung. Halten Sie Zeilen möglichst kurz (meist 80–120 Zeichen), um horizontales Scrollen zu vermeiden. Brechen Sie lange Anweisungen logisch in mehrere Zeilen auf. Nutzen Sie Leerzeichen, um logische Blöcke innerhalb einer Zeile zu trennen.
6. Objekte und Datenstrukturen erfüllen unterschiedliche Zwecke
Objekte verbergen ihre Daten hinter Abstraktionen und bieten Funktionen an, die auf diesen Daten operieren. Datenstrukturen legen ihre Daten offen und besitzen keine bedeutenden Funktionen.
Objekte vs. Datenstrukturen. Objekte kapseln Daten und bieten Verhalten über Methoden an. Sie eignen sich gut, wenn neue Typen (Klassen) hinzugefügt werden sollen, ohne bestehendes Verhalten zu ändern. Datenstrukturen hingegen legen Daten offen und haben keine wesentlichen Verhaltensweisen. Sie sind nützlich, wenn neue Verhaltensweisen hinzugefügt werden sollen, ohne die Datentypen zu verändern.
Wählen Sie den richtigen Ansatz. Verwenden Sie Objekte, wenn Sie häufig neue Typen hinzufügen, aber das Verhalten stabil halten wollen. Nutzen Sie Datenstrukturen, wenn Sie häufig neues Verhalten hinzufügen, aber die Typen stabil bleiben sollen. Dieses Verständnis hilft, flexiblere und wartbarere Systeme zu entwerfen.
Gesetz von Demeter. Bei Objekten gilt: Eine Methode sollte nur Methoden aufrufen von:
- Dem Objekt selbst
- Ihren Parametern
- Objekten, die sie selbst erzeugt
- Ihren direkten Komponentenobjekten
Dieses Prinzip reduziert die Kopplung zwischen verschiedenen Systemteilen.
7. Fehlerbehandlung sollte sauber und informativ sein
Fehlerbehandlung ist wichtig, aber wenn sie die Logik verschleiert, ist sie falsch.
Verwenden Sie Ausnahmen statt Fehlercodes. Ausnahmen bieten eine sauberere Möglichkeit, Fehler zu behandeln als traditionelle Fehlercodes. Sie trennen die Fehlerbehandlung vom Hauptcode, was beides leichter verständlich und wartbar macht.
Erstellen Sie aussagekräftige Fehlermeldungen. Fehlermeldungen sollten genügend Kontext liefern, um zu verstehen, was schiefgelaufen ist und wo. Dazu gehören:
- Welche Operation versucht wurde
- Welcher spezifische Fehler auftrat
- Relevante Werte oder Zustandsinformationen
Schreiben Sie try-catch-finally-Blöcke zuerst. Wenn Sie Code schreiben, der Ausnahmen werfen kann, beginnen Sie mit den try-catch-finally-Strukturen. So stellen Sie sicher, dass der Code von Anfang an robust gegenüber Fehlern ist und Fehlerfälle bedacht werden.
8. Unit-Tests sind entscheidend für sauberen Code
Testcode ist genauso wichtig wie Produktionscode.
Schreiben Sie Tests zuerst. Folgen Sie der Testgetriebenen Entwicklung (TDD):
- Schreiben Sie einen fehlschlagenden Test
- Schreiben Sie den minimalen Code, um den Test zu bestehen
- Refaktorieren Sie den Code, während der Test weiterhin besteht
Dieser Ansatz stellt sicher, dass Ihr Code von Anfang an testbar ist und fördert gutes Design.
Halten Sie Tests sauber. Wenden Sie dieselben Sauberkeitsstandards auf Ihren Testcode an wie auf den Produktionscode. Saubere Tests sind:
- Lesbar
- Wartbar
- Vertrauenswürdig
Beachten Sie die F.I.R.S.T.-Prinzipien für Tests:
- Schnell: Tests sollten zügig laufen
- Unabhängig: Tests sollten nicht voneinander abhängen
- Wiederholbar: Tests sollten in jeder Umgebung reproduzierbar sein
- Selbstvalidierend: Tests sollten ein klares Bestehen/Nichtbestehen liefern
- Zeitnah: Tests sollten kurz vor dem Produktionscode geschrieben werden
9. Klassen sollten klein, fokussiert und dem Prinzip der einzigen Verantwortung folgen
Die erste Regel für Klassen lautet: Sie sollten klein sein. Die zweite Regel lautet: Sie sollten noch kleiner sein.
Halten Sie Klassen fokussiert. Eine Klasse sollte eine einzige, klar definierte Verantwortung haben. Wenn Sie den Zweck einer Klasse nicht in etwa 25 Worten beschreiben können, ohne „und“ oder „oder“ zu verwenden, tut sie wahrscheinlich zu viel.
Streben Sie hohe Kohäsion an. Methoden und Variablen innerhalb einer Klasse sollten eng zusammenhängen und gemeinsam die Verantwortung der Klasse erfüllen. Geringe Kohäsion deutet oft darauf hin, dass eine Klasse zu viele Aufgaben übernimmt und aufgeteilt werden sollte.
Offen-Geschlossen-Prinzip. Entwerfen Sie Klassen so, dass sie für Erweiterungen offen, aber für Änderungen geschlossen sind. Das erreichen Sie häufig durch Abstraktionen und Schnittstellen, die neue Funktionalität erlauben, ohne bestehenden Code zu verändern.
10. Nebenläufigkeit erfordert sorgfältiges Design und Umsetzung
Sauberen nebenläufigen Code zu schreiben ist schwer – sehr schwer.
Verstehen Sie die Herausforderungen der Nebenläufigkeit. Nebenläufige Programmierung bringt Komplexitäten mit sich wie:
- Race Conditions
- Deadlocks
- Liveness-Probleme
- Performance-Einbußen
Halten Sie nebenläufigkeitsbezogenen Code getrennt. Isolieren Sie Code, der mit Nebenläufigkeit zu tun hat. Das erleichtert das Nachvollziehen, Testen und Warten sowohl der nebenläufigen als auch der nicht-nebenläufigen Teile Ihres Systems.
Nutzen Sie bewährte Bibliotheken und Frameworks. Verwenden Sie gut getestete Nebenläufigkeitsbibliotheken und Frameworks (z. B. java.util.concurrent in Java), statt selbst niedrigstufige Nebenläufigkeitskontrolle zu implementieren. Diese Werkzeuge sind für gängige Muster optimiert und gründlich geprüft.
Schreiben Sie gründliche Tests. Nebenläufigen Code zu testen ist herausfordernd, aber unerlässlich. Schreiben Sie Tests, die:
- Mehrere Threads erzeugen
- Timing und Planung variieren
- Häufig ausgeführt werden, um intermittierende Fehler zu entdecken
- Werkzeuge wie Thread-Sanitizer und statische Analysatoren nutzen, um potenzielle Nebenläufigkeitsfehler zu identifizieren
Zuletzt aktualisiert:
FAQ
What's Clean Code: A Handbook of Agile Software Craftsmanship about?
- Focus on Software Craftsmanship: The book emphasizes the importance of writing clean, maintainable code as a hallmark of professionalism in software development.
- Principles and Practices: It outlines various principles, patterns, and practices that help programmers write code that is not only functional but also easy to read and understand.
- Real-World Examples: Numerous examples of both good and bad code are included, demonstrating how to transform messy code into clean code through refactoring and disciplined practices.
Why should I read Clean Code by Robert C. Martin?
- Improve Coding Skills: Reading the book can significantly enhance your programming skills by teaching you how to write code that is easier to maintain and understand.
- Professional Development: It is a valuable resource for anyone looking to advance their career in software development, instilling a mindset of craftsmanship and quality.
- Practical Advice: The book provides practical advice that can be applied immediately in your coding practices, making it a useful guide for both novice and experienced programmers.
What are the key takeaways of Clean Code?
- Meaningful Names: The book stresses the importance of using intention-revealing names for variables, functions, and classes to enhance code readability and maintainability.
- Small Functions: Functions should be small and focused on a single task, adhering to the principle of "Do One Thing" to improve clarity and reduce complexity.
- Error Handling: Martin advocates for using exceptions rather than return codes for error handling, which helps keep the main logic of the code clean and unobscured.
What are the best quotes from Clean Code and what do they mean?
- "Clean code is a matter of discipline.": This quote emphasizes that writing clean code requires consistent effort and adherence to best practices, rather than relying on luck or talent alone.
- "Comments do not make up for bad code.": This highlights the idea that if code is poorly written, no amount of commenting can compensate for its lack of clarity and structure.
- "Leave the campground cleaner than you found it.": This metaphor encourages developers to improve the codebase with every change, ensuring that the code remains clean and maintainable over time.
How does Clean Code define clean code?
- Readable and Understandable: Clean code is defined as code that is easy to read and understand, allowing other developers to quickly grasp its purpose and functionality.
- Minimal Complexity: It should have minimal complexity, with each function and class focused on a single responsibility, making it easier to test and maintain.
- Well-Structured: Clean code is well-structured, following consistent formatting and naming conventions that enhance its clarity and reduce the cognitive load on the reader.
What is the Boy Scout Rule in Clean Code?
- Continuous Improvement: The Boy Scout Rule states that developers should "leave the campground cleaner than you found it," meaning that every time you work on code, you should strive to improve it.
- Small Changes Matter: This can be as simple as renaming a variable for clarity or refactoring a small function, which contributes to the overall cleanliness of the codebase.
- Professional Responsibility: Adhering to this rule reflects a professional attitude towards code quality and maintenance, fostering a culture of continuous improvement within a team.
What is the Single Responsibility Principle (SRP) in Clean Code?
- Definition of SRP: The SRP states that "a class should have one, and only one, reason to change." This means that each class should focus on a single responsibility or functionality.
- Benefits of SRP: Adhering to SRP leads to better organization of code, making it easier to understand, test, and maintain. It reduces the risk of changes in one area affecting unrelated parts of the code.
- Implementation Guidance: Martin provides practical advice on how to identify responsibilities and refactor classes to adhere to SRP, ensuring that code remains clean and manageable.
How does Clean Code address error handling?
- Use Exceptions: The book advocates for using exceptions rather than return codes for error handling, which helps keep the main logic of the code clean and unobscured.
- Separation of Concerns: Error handling should be separated from the main logic of the code, allowing developers to focus on the primary functionality without being bogged down by error-checking clutter.
- Provide Context: Exceptions should provide enough context to understand the source and nature of the error, making it easier to diagnose and fix issues when they arise.
What role does testing play in Clean Code?
- Foundation of Clean Code: Testing is considered a fundamental discipline in writing clean code. It ensures that the code behaves as expected and helps catch issues early in the development process.
- Fast and Reliable Tests: The book emphasizes that tests should be fast and reliable to encourage frequent execution. This helps maintain a clean codebase and reduces the risk of introducing bugs.
- Self-Validating Tests: Tests should be designed to be self-validating, meaning they should clearly indicate whether the code is functioning correctly. This reduces ambiguity and increases confidence in the code.
How does Clean Code suggest handling dependencies?
- Dependency Inversion Principle (DIP): The book explains that "high-level modules should not depend on low-level modules. Both should depend on abstractions." This principle encourages the use of interfaces and abstract classes to reduce coupling.
- Use of Dependency Injection: Martin recommends using dependency injection to manage dependencies, allowing for more flexible and testable code. This approach decouples the creation of dependencies from their usage.
- Benefits of Managing Dependencies: By managing dependencies effectively, developers can create systems that are easier to maintain and extend, leading to cleaner and more robust code.
What are some common code smells identified in Clean Code?
- Duplicated Code: This is a major code smell that indicates a lack of abstraction. The book advises eliminating duplication to improve maintainability and reduce errors.
- Long Methods: Methods that are too long can be difficult to understand and maintain. The book suggests breaking them down into smaller, more manageable functions.
- Excessive Comments: While comments can be helpful, excessive or redundant comments often indicate that the code itself is not clear. The goal should be to write self-explanatory code that requires minimal comments.
How can I apply the principles from Clean Code in my own projects?
- Start with Small Changes: Begin by applying the principles of clean code to small sections of your codebase. Refactor one class or function at a time to improve readability and maintainability.
- Write Tests First: Adopt Test-Driven Development (TDD) practices by writing tests before implementing new features. This ensures that your code is always covered by tests and helps maintain quality.
- Regularly Refactor: Make refactoring a regular part of your development process. Continuously look for opportunities to improve code structure and eliminate duplication, keeping your codebase clean and efficient.
Rezensionen
Clean Code gilt als unverzichtbares Werk für Softwareentwickler und bietet wertvolle Einsichten in das Schreiben von lesbarem und wartbarem Code. Während das Buch für seine praxisnahen Ratschläge zu Benennungskonventionen, Funktionsgestaltung und Testverfahren gelobt wird, empfinden einige Leser den Fokus auf Java als zu dominant und manche Empfehlungen als mitunter zu radikal. Die Fallstudien stoßen auf gemischte Resonanz: Manche finden sie äußerst hilfreich, andere weniger überzeugend. Trotz dieser Schwächen betrachten viele Entwickler das Buch als Pflichtlektüre, die ihre Programmierpraxis und ihr Verständnis von Software-Handwerk nachhaltig verbessert hat.
Similar Books









