O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Clean Code - Refactoring, Patterns, Testen und Techniken für sauberen Code

Book Description

  • Kommentare, Formatierung, Strukturierung
  • Fehler-Handling und Unit-Tests
  • Zahlreiche Fallstudien, Best Practices, Heuristiken und Code Smells
Selbst schlechter Code kann funktionieren. Aber wenn der Code nicht sauber ist, kann er ein Entwicklungsunternehmen in die Knie zwingen. Jedes Jahr gehen unzählige Stunden und beträchtliche Ressourcen verloren, weil Code schlecht geschrieben ist. Aber das muss nicht sein. Mit Clean Code präsentiert Ihnen der bekannte Software-Experte Robert C. Martin ein revolutionäres Paradigma, mit dem er Ihnen aufzeigt, wie Sie guten Code schreiben und schlechten Code überarbeiten. Zusammen mit seinen Kollegen von Object Mentor destilliert er die besten Praktiken der agilen Entwicklung von sauberem Code zu einem einzigartigen Buch. So können Sie sich die Erfahrungswerte der Meister der Software-Entwicklung aneignen, die aus Ihnen einen besseren Programmierer machen werden – anhand konkreter Fallstudien, die im Buch detailliert durchgearbeitet werden. Sie werden in diesem Buch sehr viel Code lesen. Und Sie werden aufgefordert, darüber nachzudenken, was an diesem Code richtig und falsch ist. Noch wichtiger: Sie werden herausgefordert, Ihre professionellen Werte und Ihre Einstellung zu Ihrem Beruf zu überprüfen.

Aus dem Inhalt:
  • Lernen Sie, guten Code von schlechtem zu unterscheiden
  • Sauberen Code schreiben und schlechten Code in guten umwandeln
  • Aussagekräftige Namen sowie gute Funktionen, Objekte und Klassen erstellen
  • Code so formatieren, strukturieren und kommentieren, dass er bestmöglich lesbar ist
  • Ein vollständiges Fehler-Handling implementieren, ohne die Logik des Codes zu verschleiern
  • Unit-Tests schreiben und Ihren Code testgesteuert entwickeln

Table of Contents

  1. Impressum
  2. Vorwort
  3. Einführung
    1. Danksagungen
  4. Kapitel 1: Sauberer Code
    1. 1.1 Code, Code und nochmals Code
    2. 1.2 Schlechter Code
    3. 1.3 Die Lebenszykluskosten eines Chaos
      1. Das große Redesign in den Wolken
      2. Einstellung
      3. Das grundlegende Problem
      4. Sauberen Code schreiben – eine Kunst?
      5. Was ist sauberer Code​?
    4. 1.4 Denkschulen​
    5. 1.5 Wir sind Autoren
    6. 1.6 Die Pfadfinder-Rege​l
    7. 1.7 Vorläufer und Prinzipien
    8. 1.8 Zusammenfassung
  5. Kapitel 2: Aussagekräftige Namen
    1. 2.1 Einführung
    2. 2.2 Zweckbeschreibende Namen​ wählen
    3. 2.3 Fehlinformationen​ vermeiden
    4. 2.4 Unterschiede deutlich​ machen
    5. 2.5 Aussprechbare Namen​ verwenden
    6. 2.6 Suchbare Namen​ verwenden
    7. 2.7 Codierungen​ vermeiden
      1. Ungarische Notation​
      2. Member-Präfixe​
      3. Interfaces​ und Implementierungen​
    8. 2.8 ​Mentale Mappings vermeiden
    9. 2.9 Klassennamen​​
    10. 2.10 Methodennamen​​
    11. 2.11 Vermeiden Sie humorige Namen
    12. 2.12 Wählen Sie ein Wort pro Konzept
    13. 2.13 Keine Wortspiele​
    14. 2.14 Namen der Lösungsdomäne​ verwenden
    15. 2.15 Namen der Problemdomäne verwenden
    16. 2.16 Bedeutungsvollen Kontext​ hinzufügen
    17. 2.17 Keinen überflüssigen Kontext​ hinzufügen
    18. 2.18 Abschließende Worte
  6. Kapitel 3: Funktionen
    1. 3.1 Klein!
      1. Blöcke und Einrückungen
    2. 3.2 Eine Aufgabe erfüllen
      1. Abschnitte innerhalb von Funktionen​
    3. 3.3 Eine Abstraktionsebene pro Funktion​​
      1. Code Top-down lesen: die Stepdown-Regel
    4. 3.4 Switch-Anweisungen​
    5. 3.5 Beschreibende Namen​​ verwenden
    6. 3.6 ​Funktionsargumente
      1. Gebräuchliche monadische​ Formen
      2. Flag-Argumente
      3. Dyadische Funktionen​
      4. Triaden​
      5. Argument-Objekte
      6. Argument-Listen
      7. Verb​en und Schlüsselwörter​
    7. 3.7 Nebeneffekt​e vermeiden
      1. Output-Argumente
    8. 3.8 Anweisung und Abfrage trennen
    9. 3.9 Ausnahmen sind besser als Fehler-Codes
      1. Try/Catch-Blöcke​ extrahieren
      2. ​Fehler-Verarbeitung ist eine Aufgabe
      3. Der Abhängigkeitsmagnet Error.java​​
    10. 3.10 Don’t Repeat Yourself
    11. 3.11 Strukturierte Programmierung​​
    12. 3.12 Wie schreibt man solche Funktionen?
    13. 3.13 Zusammenfassung
    14. 3.14 SetupTeardownIncluder
  7. Kapitel 4: Kommentare
    1. 4.1 Kommentare sind kein Ersatz für schlechten Code
    2. 4.2 Erklären Sie im und durch den Code
    3. 4.3 Gute Kommentare​
      1. Juristische Kommentare​
      2. Informierende Kommentare​
      3. Erklärung der Absicht
      4. Klarstellungen
      5. Warnungen vor Konsequenzen
      6. TODO-Kommentare​
      7. Verstärkung
      8. ​Javadocs in öffentlichen APIs
    4. 4.4 Schlechte Kommentare​
      1. Geraune
      2. Redundante Kommentare​
      3. Irreführende Kommentare
      4. Vorgeschriebene Kommentare​
      5. Tagebuch-Kommentare​
      6. Geschwätz​
      7. Beängstigendes Geschwätz
      8. Verwenden Sie keinen Kommentar, wenn Sie eine Funktion oder eine Variable verwenden können
      9. Positionsbezeichner​
      10. Kommentare hinter schließenden Klammern​
      11. Zuschreibungen und Nebenbemerkungen
      12. Auskommentierter Code​​
      13. HTML-Kommentare​​
      14. Nicht-lokale Informationen​
      15. Zu viele Informationen
      16. Unklarer Zusammenhang
      17. Funktions-Header​​
      18. Javadocs in nicht-öffentlichem Code
      19. Beispiel
  8. Kapitel 5: Formatierung
    1. 5.1 Der Zweck der Formatierung​
    2. 5.2 Vertikale Formatierung​
      1. Die Zeitungs-Metapher​​
      2. Vertikale Offenheit​​ zwischen Konzepten
      3. Vertikale Dichte​​
      4. Vertikaler Abstand​​
      5. Vertikale Anordnung​​
    3. 5.3 Horizontale Formatierung​
      1. Horizontale Offenheit und Dichte
      2. Horizontale Ausrichtung​​
      3. Einrückung​​
      4. Dummy-Bereiche​
    4. 5.4 Team-Regeln​​
    5. 5.5 Uncle Bobs Formatierungsregeln​
  9. Kapitel 6: Objekte und Datenstrukturen
    1. 6.1 Datenabstraktion​
    2. 6.2 Daten/Objekt-Anti-Symmetrie​​​
    3. 6.3 Das Law of Demeter
      1. Zugkatastrophe
      2. Hybride​
      3. Struktur verbergen
    4. 6.4 Datentransfer-Objekte
      1. Active Record
    5. 6.5 Zusammenfassung
  10. Kapitel 7: Fehler-Handling
    1. 7.1 Ausnahme​n statt Rückgabe-Codes​
    2. 7.2 Try-Catch-Finally-Anweisungen zuerst schreiben
    3. 7.3 Unchecked Exception​​​s
    4. 7.4 Ausnahmen mit Kontext auslösen​
    5. 7.5 Definieren Sie Exception-Klassen mit Blick auf die Anforderungen des Aufrufers
    6. 7.6 Den normalen Ablauf definieren
    7. 7.7 Keine ​Null zurückgeben
    8. 7.8 Keine Null übergeben
    9. 7.9 Zusammenfassung
  11. Kapitel 8: Grenzen
    1. 8.1 Mit Drittanbieter-Code​​ arbeiten
    2. 8.2 Grenzen erforschen und kennen lernen
    3. 8.3 ​log4j kennen lernen
    4. 8.4 Lern-Tests sind besser als kostenlos
    5. 8.5 Code verwenden, der noch nicht existiert
    6. 8.6 Saubere Grenzen
  12. Kapitel 9: Unit-Tests
    1. 9.1 Die drei Gesetze​ der TDD
    2. 9.2 Tests sauber halten​
      1. Tests ermöglichen die -heiten und -keiten
    3. 9.3 Saubere Tests​
      1. Domänenspezifische Testsprache​
      2. Ein Doppelstandard​
    4. 9.4 Ein assert pro Test​
      1. Ein Konzept pro Test​
    5. 9.5 ​F.I.R.S.T. ​
    6. 9.6 Zusammenfassung
  13. Kapitel 10: Klassen
    1. 10.1 Klassenaufbau
      1. Einkapselung
    2. 10.2 Klassen sollten klein sein!
      1. Fünf Methoden sind nicht zu viel, oder?
      2. Das Single-Responsibility-Prinzip​
      3. Kohäsion​
      4. Kohäsion zu erhalten, führt zu vielen kleinen Klassen
    3. 10.3 Änderungen einplanen
      1. Änderungen isolieren
  14. Kapitel 11: Systeme
    1. 11.1 Wie baut man eine Stadt?
    2. 11.2 Konstruktion und Anwendung eines Systems trennen
      1. Trennung in main
      2. Factories
      3. Dependency Injection
    3. 11.3 Aufwärtsskalierung​
      1. Cross-Cutting Concerns
    4. 11.4 ​Java-Proxies
    5. 11.5 Reine Java-AOP-Frameworks
    6. 11.6 ​AspectJ-Aspekte
    7. 11.7 Die Systemarchitektur testen
    8. 11.8 Die Entscheidungsfindung optimieren
    9. 11.9 ​Standards weise anwenden, wenn sie nachweisbar einen Mehrwert bieten
    10. 11.10 Systeme brauchen domänenspezifische Sprachen
    11. 11.11 Zusammenfassung
  15. Kapitel 12: Emergenz
    1. 12.1 Saubere Software durch emergentes Design
    2. 12.2 Einfache Design-Regel 1: Alle Tests bestehen
    3. 12.3 Einfache Design-Regeln 2–4: Refactoring​
    4. 12.4 Keine Duplizierung
    5. 12.5 Ausdrucksstärke
    6. 12.6 Minimale Klassen und Methoden
    7. 12.7 Zusammenfassung
  16. Kapitel 13: Nebenläufigkeit
    1. 13.1 Warum Nebenläufigkeit?
      1. Mythen und falsche Vorstellungen
    2. 13.2 Herausforderungen
    3. 13.3 Prinzipien einer defensiven Nebenläufigkeitsprogrammierung
      1. Single-Responsibility-Prinzip​
      2. Korollar: Beschränken Sie den Gültigkeitsbereich von Daten
      3. Korollar: Arbeiten Sie mit Kopien der Daten
      4. Korollar: Threads sollten voneinander so unabhängig wie möglich sein
    4. 13.4 Lernen Sie Ihre Library kennen
      1. Thread-sichere Collections
    5. 13.5 Lernen Sie Ihre Ausführungsmodelle kennen
      1. Erzeuger-Verbraucher
      2. Leser-Schreiber
      3. Philosophenproblem
    6. 13.6 Achten Sie auf Abhängigkeiten zwischen synchronisierten Methoden
    7. 13.7 Halten Sie synchronisierte Abschnitte klein
    8. 13.8 Korrekten Shutdown-Code zu schreiben, ist schwer
    9. 13.9 Threaded-Code testen
      1. Behandeln Sie gelegentlich auftretende Fehler als potenzielle Threading-Probleme
      2. Bringen Sie erst den Nonthreaded-Code zum Laufen
      3. Machen Sie Ihren Threaded-Code pluggable
      4. Schreiben Sie anpassbaren Threaded-Code
      5. Den Code mit mehr Threads als Prozessoren ausführen
      6. Den Code auf verschiedenen Plattformen ausführen
      7. Code-Scheitern durch Instrumentierung provozieren
      8. Manuelle Codierung
      9. Automatisiert
    10. 13.10 Zusammenfassung
  17. Kapitel 14: Schrittweise Verfeinerung
    1. 14.1 Args-Implementierung
      1. Wie habe ich dies gemacht?
    2. 14.2 Args: der Rohentwurf
      1. Deshalb hörte ich auf
      2. Über inkrementelle Entwicklung​​
    3. 14.3 String-Argumente
    4. 14.4 Zusammenfassung
  18. Kapitel 15: JUnit im Detail
    1. 15.1 Das JUnit-Framework
    2. 15.2 Zusammenfassung
  19. Kapitel 16: Refactoring von SerialDate
    1. 16.1 Zunächst bring es zum Laufen!
    2. 16.2 Dann mach es richtig!
    3. 16.3 Zusammenfassung
  20. Kapitel 17: Smells und Heuristiken
    1. 17.1 Kommentar​e
      1. ​C1: Ungeeignete​ Informationen
      2. ​C2: Überholte Kommenta​re
      3. ​C3: Redundante Kommentare
      4. ​C4: Schlecht geschriebene Kommentare​
      5. ​C5: Auskommentierter Code​
    2. 17.2 Umgebung
      1. ​E1: Ein Build​ erfordert mehr als einen Schritt
      2. ​E2: Tests erfordern mehr als einen Schritt
    3. 17.3 Funktion​en
      1. ​F1: Zu viele Argumente​​
      2. ​F2: Output-Argumente​​
      3. ​F3: Flag-Argument​​e
      4. ​F4: Tote Funktione​n
    4. 17.4 Allgemein
      1. ​G1: Mehrere Sprache​n in einer Quelldatei​
      2. ​G2: Offensichtliches Verhalten​ ist nicht implementiert
      3. ​G3: Falsches Verhalten an den Grenzen
      4. ​G4: Übergangene Sicherungen​
      5. ​G5: Duplizierung​
      6. ​G6: Auf der falschen Abstraktionsebene​ codieren
      7. ​G7: Basisklasse​​ hängt von abgeleiteten Klassen​​ ab
      8. ​G8: Zu viele Informationen
      9. ​G9: Toter Code
      10. ​G10: Vertikale Trennung​
      11. ​G11: Inkonsistenz​
      12. ​G12: Müll​​
      13. ​G13: Künstliche Kopplung​
      14. ​G14: Funktionsneid​
      15. ​G15: Selektor-Argumente​​
      16. ​G16: Verdeckte Absicht
      17. ​G17: Falsche Zuständigkeit​
      18. ​G18: Fälschlich als statisch deklarierte Methode​n
      19. ​G19: Aussagekräftige Variable​n verwenden
      20. ​G20: Funktionsname​​ sollte die Aktion ausdrücken
      21. ​G21: Den Algorithmus​ verstehen
      22. ​G22: Logische Abhängigkeiten in physische umwandeln
      23. ​G23: Polymorphismus​ statt If/Else oder Switch/Case verwenden
      24. ​G24: Konvention​​en beachten
      25. ​G25: Magische Zahlen​ durch benannte Konstanten ersetzen
      26. ​G26: Präzise sein
      27. ​G27: Struktur ist wichtiger als Konvention
      28. ​G28: Bedingungen​​ einkapseln
      29. ​G29: Negative Bedingungen​ vermeiden
      30. ​G30: Eine Aufgabe pro Funktion​!
      31. ​G31: Verborgene zeitliche Kopplungen​
      32. ​G32: Keine Willkür
      33. ​G33: Grenzbedingungen einkapseln
      34. ​G34: In Funktionen nur eine Abstraktionsebene​​ tiefer gehen
      35. ​G35: Konfigurierbare Daten hoch ansiedeln
      36. ​G36: Transitive Navigation​ vermeiden
    5. 17.5 Java
      1. ​J1: Lange Importlisten​ durch Platzhalter​ vermeiden
      2. ​J2: Keine Konstanten vererben​
      3. ​J3: Konstanten im Gegensatz zu Enums​
    6. 17.6 Namen​
      1. ​N1: Deskriptive Namen​ wählen
      2. ​N2: Namen sollten der Abstraktionsebene​ entsprechen
      3. ​N3: Möglichst die Standardnomenklatur​ verwenden
      4. ​N4: Eindeutige Namen​
      5. ​N5: Lange Namen​ für große Geltungsbereiche
      6. ​N6: Codierungen vermeiden
      7. ​N7: Namen sollten Nebeneffekte​ beschreiben
    7. 17.7 Test​s
      1. ​T1: Unzureichende Tests​
      2. ​T2: Ein Coverage-Tool​ verwenden
      3. ​T3: Triviale Tests​ nicht überspringen
      4. ​T4: Ein ignorierter Test zeigt eine Mehrdeutigkeit​ auf
      5. ​T5: Grenzbedingung​​en testen
      6. ​T6: Bei Bugs die Nachbarschaft gründlich testen
      7. ​T7: Das Muster des Scheiterns zur Diagnose nutzen
      8. ​T8: Hinweise durch Coverage-Patterns
      9. ​T9: Tests sollten schnell sein
    8. 17.8 Zusammenfassung
  21. Anhang A: Nebenläufigkeit II
    1. A.1 Client/Server-Beispiel
      1. Der Server
      2. Threading hinzufügen
      3. Server-Beobachtungen
      4. Zusammenfassung
    2. A.2 Mögliche Ausführungspfade
      1. Anzahl der Pfade
      2. Tiefer graben
      3. Zusammenfassung
    3. A.3 Lernen Sie Ihre Library kennen
      1. Executor Framework
      2. Nicht blockierende Lösungen
      3. Nicht thread-sichere Klassen​
    4. A.4 Abhängigkeiten zwischen Methoden können nebenläufigen Code beschädigen
      1. Das Scheitern tolerieren
      2. Clientbasiertes Locking
      3. Serverbasiertes Locking
    5. A.5 Den Durchsatz verbessern
      1. Single-Thread-Berechnung des Durchsatzes
      2. Multithread-Berechnung des Durchsatzes
    6. A.6 Deadlock​
      1. Gegenseitiger Ausschluss​
      2. Sperren & warten
      3. Keine präemptive Aktion
      4. Zirkuläres Warten
      5. Den gegenseitigen Ausschluss aufheben
      6. Das Sperren & Warten aufheben
      7. Die Präemption umgehen
      8. Das zirkuläre Warten umgehen
    7. A.7 Multithreaded-Code testen
    8. A.8 Threadbasierten Code mit Tools testen
    9. A.9 Zusammenfassung
    10. A.10 Tutorial: kompletter Beispielcode
      1. Client/Server ohne Threads
      2. Client/Server mit Threads
  22. Anhang B: org.jfree.date.SerialDate
  23. Anhang C: Literaturverweise
  24. Epilog