Inhaltsverzeichnis

Impressum

Vorwort

Einführung

Danksagungen

Kapitel 1: Sauberer Code

1.1 Code, Code und nochmals Code

1.2 Schlechter Code

1.3 Die Lebenszykluskosten eines Chaos

Das große Redesign in den Wolken

Einstellung

Das grundlegende Problem

Sauberen Code schreiben – eine Kunst?

Was ist sauberer Code​?

1.4 Denkschulen​

1.5 Wir sind Autoren

1.6 Die Pfadfinder-Rege​l

1.7 Vorläufer und Prinzipien

1.8 Zusammenfassung

Kapitel 2: Aussagekräftige Namen

2.1 Einführung

2.2 Zweckbeschreibende Namen​ wählen

2.3 Fehlinformationen​ vermeiden

2.4 Unterschiede deutlich​ machen

2.5 Aussprechbare Namen​ verwenden

2.6 Suchbare Namen​ verwenden

2.7 Codierungen​ vermeiden

Ungarische Notation​

Member-Präfixe​

Interfaces​ und Implementierungen​

2.8 ​Mentale Mappings vermeiden

2.9 Klassennamen​​

2.10 Methodennamen​​

2.11 Vermeiden Sie humorige Namen

2.12 Wählen Sie ein Wort pro Konzept

2.13 Keine Wortspiele​

2.14 Namen der Lösungsdomäne​ verwenden

2.15 Namen der Problemdomäne verwenden

2.16 Bedeutungsvollen Kontext​ hinzufügen

2.17 Keinen überflüssigen Kontext​ hinzufügen

2.18 Abschließende Worte

Kapitel 3: Funktionen

3.1 Klein!

Blöcke und Einrückungen

3.2 Eine Aufgabe erfüllen

Abschnitte innerhalb von Funktionen​

3.3 Eine Abstraktionsebene pro Funktion​​

Code Top-down lesen: die Stepdown-Regel

3.4 Switch-Anweisungen​

3.5 Beschreibende Namen​​ verwenden

3.6 ​Funktionsargumente

Gebräuchliche monadische​ Formen

Flag-Argumente

Dyadische Funktionen​

Triaden​

Argument-Objekte

Argument-Listen

Verb​en und Schlüsselwörter​

3.7 Nebeneffekt​e vermeiden

Output-Argumente

3.8 Anweisung und Abfrage trennen

3.9 Ausnahmen sind besser als Fehler-Codes

Try/Catch-Blöcke​ extrahieren

​Fehler-Verarbeitung ist eine Aufgabe

Der Abhängigkeitsmagnet Error.java​​

3.10 Don’t Repeat Yourself

3.11 Strukturierte Programmierung​​

3.12 Wie schreibt man solche Funktionen?

3.13 Zusammenfassung

3.14 SetupTeardownIncluder

Kapitel 4: Kommentare

4.1 Kommentare sind kein Ersatz für schlechten Code

4.2 Erklären Sie im und durch den Code

4.3 Gute Kommentare​

Juristische Kommentare​

Informierende Kommentare​

Erklärung der Absicht

Klarstellungen

Warnungen vor Konsequenzen

TODO-Kommentare​

Verstärkung

​Javadocs in öffentlichen APIs

4.4 Schlechte Kommentare​

Geraune

Redundante Kommentare​

Irreführende Kommentare

Vorgeschriebene Kommentare​

Tagebuch-Kommentare​

Geschwätz​

Beängstigendes Geschwätz

Verwenden Sie keinen Kommentar, wenn Sie eine Funktion oder eine Variable verwenden können

Positionsbezeichner​

Kommentare hinter schließenden Klammern​

Zuschreibungen und Nebenbemerkungen

Auskommentierter Code​​

HTML-Kommentare​​

Nicht-lokale Informationen​

Zu viele Informationen

Unklarer Zusammenhang

Funktions-Header​​

Javadocs in nicht-öffentlichem Code

Beispiel

Kapitel 5: Formatierung

5.1 Der Zweck der Formatierung​

5.2 Vertikale Formatierung​

Die Zeitungs-Metapher​​

Vertikale Offenheit​​ zwischen Konzepten

Vertikale Dichte​​

Vertikaler Abstand​​

Vertikale Anordnung​​

5.3 Horizontale Formatierung​

Horizontale Offenheit und Dichte

Horizontale Ausrichtung​​

Einrückung​​

Dummy-Bereiche​

5.4 Team-Regeln​​

5.5 Uncle Bobs Formatierungsregeln​

Kapitel 6: Objekte und Datenstrukturen

6.1 Datenabstraktion​

6.2 Daten/Objekt-Anti-Symmetrie​​​

6.3 Das Law of Demeter

Zugkatastrophe

Hybride​

Struktur verbergen

6.4 Datentransfer-Objekte

Active Record

6.5 Zusammenfassung

Kapitel 7: Fehler-Handling

7.1 Ausnahme​n statt Rückgabe-Codes​

7.2 Try-Catch-Finally-Anweisungen zuerst schreiben

7.3 Unchecked Exception​​​s

7.4 Ausnahmen mit Kontext auslösen​

7.5 Definieren Sie Exception-Klassen mit Blick auf die Anforderungen des Aufrufers

7.6 Den normalen Ablauf definieren

7.7 Keine ​Null zurückgeben

7.8 Keine Null übergeben

7.9 Zusammenfassung

Kapitel 8: Grenzen

8.1 Mit Drittanbieter-Code​​ arbeiten

8.2 Grenzen erforschen und kennen lernen

8.3 ​log4j kennen lernen

8.4 Lern-Tests sind besser als kostenlos

8.5 Code verwenden, der noch nicht existiert

8.6 Saubere Grenzen

Kapitel 9: Unit-Tests

9.1 Die drei Gesetze​ der TDD

9.2 Tests sauber halten​

Tests ermöglichen die -heiten und -keiten

9.3 Saubere Tests​

Domänenspezifische Testsprache​

Ein Doppelstandard​

9.4 Ein assert pro Test​

Ein Konzept pro Test​

9.5 ​F.I.R.S.T. ​

9.6 Zusammenfassung

Kapitel 10: Klassen

10.1 Klassenaufbau

Einkapselung

10.2 Klassen sollten klein sein!

Fünf Methoden sind nicht zu viel, oder?

Das Single-Responsibility-Prinzip​

Kohäsion​

Kohäsion zu erhalten, führt zu vielen kleinen Klassen

10.3 Änderungen einplanen

Änderungen isolieren

Kapitel 11: Systeme

11.1 Wie baut man eine Stadt?

11.2 Konstruktion und Anwendung eines Systems trennen

Trennung in main

Factories

Dependency Injection

11.3 Aufwärtsskalierung​

Cross-Cutting Concerns

11.4 ​Java-Proxies

11.5 Reine Java-AOP-Frameworks

11.6 ​AspectJ-Aspekte

11.7 Die Systemarchitektur testen

11.8 Die Entscheidungsfindung optimieren

11.9 ​Standards weise anwenden, wenn sie nachweisbar einen Mehrwert bieten

11.10 Systeme brauchen domänenspezifische Sprachen

11.11 Zusammenfassung

Kapitel 12: Emergenz

12.1 Saubere Software durch emergentes Design

12.2 Einfache Design-Regel 1: Alle Tests bestehen

12.3 Einfache Design-Regeln 2–4: Refactoring​

12.4 Keine Duplizierung

12.5 Ausdrucksstärke

12.6 Minimale Klassen und Methoden

12.7 Zusammenfassung

Kapitel 13: Nebenläufigkeit

13.1 Warum Nebenläufigkeit?

Mythen und falsche Vorstellungen

13.2 Herausforderungen

13.3 Prinzipien einer defensiven Nebenläufigkeitsprogrammierung

Single-Responsibility-Prinzip​

Korollar: Beschränken Sie den Gültigkeitsbereich von Daten

Korollar: Arbeiten Sie mit Kopien der Daten

Korollar: Threads sollten voneinander so unabhängig wie möglich sein

13.4 Lernen Sie Ihre Library kennen

Thread-sichere Collections

13.5 Lernen Sie Ihre Ausführungsmodelle kennen

Erzeuger-Verbraucher

Leser-Schreiber

Philosophenproblem

13.6 Achten Sie auf Abhängigkeiten zwischen synchronisierten Methoden

13.7 Halten Sie synchronisierte Abschnitte klein

13.8 Korrekten Shutdown-Code zu schreiben, ist schwer

13.9 Threaded-Code testen

Behandeln Sie gelegentlich auftretende Fehler als potenzielle Threading-Probleme

Bringen Sie erst den Nonthreaded-Code zum Laufen

Machen Sie Ihren Threaded-Code pluggable

Schreiben Sie anpassbaren Threaded-Code

Den Code mit mehr Threads als Prozessoren ausführen

Den Code auf verschiedenen Plattformen ausführen

Code-Scheitern durch Instrumentierung provozieren

Manuelle Codierung

Automatisiert

13.10 Zusammenfassung

Kapitel 14: Schrittweise Verfeinerung

14.1 Args-Implementierung

Wie habe ich dies gemacht?

14.2 Args: der Rohentwurf

Deshalb hörte ich auf

Über inkrementelle Entwicklung​​

14.3 String-Argumente

14.4 Zusammenfassung

Kapitel 15: JUnit im Detail

15.1 Das JUnit-Framework

15.2 Zusammenfassung

Kapitel 16: Refactoring von SerialDate

16.1 Zunächst bring es zum Laufen!

16.2 Dann mach es richtig!

16.3 Zusammenfassung

Kapitel 17: Smells und Heuristiken

17.1 Kommentar​e

​C1: Ungeeignete​ Informationen

​C2: Überholte Kommenta​re

​C3: Redundante Kommentare

​C4: Schlecht geschriebene Kommentare​

​C5: Auskommentierter Code​

17.2 Umgebung

​E1: Ein Build​ erfordert mehr als einen Schritt

​E2: Tests erfordern mehr als einen Schritt

17.3 Funktion​en

​F1: Zu viele Argumente​​

​F2: Output-Argumente​​

​F3: Flag-Argument​​e

​F4: Tote Funktione​n

17.4 Allgemein

​G1: Mehrere Sprache​n in einer Quelldatei​

​G2: Offensichtliches Verhalten​ ist nicht implementiert

​G3: Falsches Verhalten an den Grenzen

​G4: Übergangene Sicherungen​

​G5: Duplizierung​

​G6: Auf der falschen Abstraktionsebene​ codieren

​G7: Basisklasse​​ hängt von abgeleiteten Klassen​​ ab

​G8: Zu viele Informationen

​G9: Toter Code

​G10: Vertikale Trennung​

​G11: Inkonsistenz​

​G12: Müll​​

​G13: Künstliche Kopplung​

​G14: Funktionsneid​

​G15: Selektor-Argumente​​

​G16: Verdeckte Absicht

​G17: Falsche Zuständigkeit​

​G18: Fälschlich als statisch deklarierte Methode​n

​G19: Aussagekräftige Variable​n verwenden

​G20: Funktionsname​​ sollte die Aktion ausdrücken

​G21: Den Algorithmus​ verstehen

​G22: Logische Abhängigkeiten in physische umwandeln

​G23: Polymorphismus​ statt If/Else oder Switch/Case verwenden

​G24: Konvention​​en beachten

​G25: Magische Zahlen​ durch benannte Konstanten ersetzen

​G26: Präzise sein

​G27: Struktur ist wichtiger als Konvention

​G28: Bedingungen​​ einkapseln

​G29: Negative Bedingungen​ vermeiden

​G30: Eine Aufgabe pro Funktion​!

​G31: Verborgene zeitliche Kopplungen​

​G32: Keine Willkür

​G33: Grenzbedingungen einkapseln

​G34: In Funktionen nur eine Abstraktionsebene​​ tiefer gehen

​G35: Konfigurierbare Daten hoch ansiedeln

​G36: Transitive Navigation​ vermeiden

17.5 Java

​J1: Lange Importlisten​ durch Platzhalter​ vermeiden

​J2: Keine Konstanten vererben​

​J3: Konstanten im Gegensatz zu Enums​

17.6 Namen​

​N1: Deskriptive Namen​ wählen

​N2: Namen sollten der Abstraktionsebene​ entsprechen

​N3: Möglichst die Standardnomenklatur​ verwenden

​N4: Eindeutige Namen​

​N5: Lange Namen​ für große Geltungsbereiche

​N6: Codierungen vermeiden

​N7: Namen sollten Nebeneffekte​ beschreiben

17.7 Test​s

​T1: Unzureichende Tests​

​T2: Ein Coverage-Tool​ verwenden

​T3: Triviale Tests​ nicht überspringen

​T4: Ein ignorierter Test zeigt eine Mehrdeutigkeit​ auf

​T5: Grenzbedingung​​en testen

​T6: Bei Bugs die Nachbarschaft gründlich testen

​T7: Das Muster des Scheiterns zur Diagnose nutzen

​T8: Hinweise durch Coverage-Patterns

​T9: Tests sollten schnell sein

17.8 Zusammenfassung

Anhang A: Nebenläufigkeit II

A.1 Client/Server-Beispiel

Der Server

Threading hinzufügen

Server-Beobachtungen

Zusammenfassung

A.2 Mögliche Ausführungspfade

Anzahl der Pfade

Tiefer graben

Zusammenfassung

A.3 Lernen Sie Ihre Library kennen

Executor Framework

Nicht blockierende Lösungen

Nicht thread-sichere Klassen​

A.4 Abhängigkeiten zwischen Methoden können nebenläufigen Code beschädigen

Das Scheitern tolerieren

Clientbasiertes Locking

Serverbasiertes Locking

A.5 Den Durchsatz verbessern

Single-Thread-Berechnung des Durchsatzes

Multithread-Berechnung des Durchsatzes

A.6 Deadlock​

Gegenseitiger Ausschluss​

Sperren & warten

Keine präemptive Aktion

Zirkuläres Warten

Den gegenseitigen Ausschluss aufheben

Das Sperren & Warten aufheben

Die Präemption umgehen

Das zirkuläre Warten umgehen

A.7 Multithreaded-Code testen

A.8 Threadbasierten Code mit Tools testen

A.9 Zusammenfassung

A.10 Tutorial: kompletter Beispielcode

Client/Server ohne Threads

Client/Server mit Threads

Anhang B: org.jfree.date.SerialDate

Anhang C: Literaturverweise

Epilog

Clean Code

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

Robert C. Martin

Unter Mitarbeit von:
Michael C. Feathers, Timothy R. Ottinger, Jeffrey J. Langr, Brett L. Schuchert, James W. Grenning, Kevin Dean Wampler
Object Mentor, Inc.

Übersetzt aus dem Amerikanischen von Reinhard Engel

Impressum

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über <http://dnb.d-nb.de> abrufbar.

ISBN 978-3-8266-9639-8

1. Auflage 2009

www.mitp.de

E-Mail: kundenservice@hjr-verlag.de

Telefon: +49 6221 / 489 -555

Telefax: +49 6221 / 489 -410

© 2009 mitp, eine Marke der Verlagsgruppe Hüthig Jehle Rehm GmbH Heidelberg, München, Landsberg, Frechen, Hamburg

Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.

Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.

Authorized translation from the English language edition, entitled CLEAN CODE: A HANDBOOK OF AGILE SOFTWARE CRAFTSMANSHIP, 1 st Edition, 0132350882 by MARTIN, ROBERT C., published by Pearson Education, Inc, publishing as Prentice Hall, Copyright © 2009 Pearson Education, Inc.

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. GERMAN language edition published by mitp-Verlag, VERLAGSGRUPPE HÜTHIG JEHLE REHM GMBH, Copyright © 2009.

Lektorat: Sabine Schulz

Korrektorat: Petra Heubach-Erdmann

electronic publication: III-satz, Husby, www.drei-satz.de

Dieses Ebook verwendet das ePub-Format und ist optimiert für die Nutzung mit dem iBooks-reader auf dem iPad von Apple. Bei der Verwendung anderer Reader kann es zu Darstellungsproblemen kommen.

Der Verlag räumt Ihnen mit dem Kauf des ebooks das Recht ein, die Inhalte im Rahmen des geltenden Urheberrechts zu nutzen. Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheherrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und Einspeicherung und Verarbeitung in elektronischen Systemen.

Der Verlag schützt seine ebooks vor Missbrauch des Urheberrechts durch ein digitales Rechtemanagement. Bei Kauf im Webshop des Verlages werden die ebooks mit einem nicht sichtbaren digitalen Wasserzeichen individuell pro Nutzer signiert.

Bei Kauf in anderen ebook-Webshops erfolgt die Signatur durch die Shopbetreiber. Angaben zu diesem DRM finden Sie auf den Seiten der jeweiligen Anbieter.

Vorwort

Bei uns in Dänemark zählt Ga-Jol zu den beliebtesten Süßigkeiten. Sein starker Lakritzduft ist ein perfektes Mittel gegen unser feuchtes und oft kühles Wetter. Der Charme, den Ga-Jol für uns Dänen entfaltet, liegt auch an den weisen oder geistreichen Sprüchen, die auf dem Deckel jeder Packung abgedruckt sind. Ich habe mir heute Morgen eine Doppelpackung dieser Köstlichkeit gekauft und fand darauf das folgende alte dänische Sprichwort:

Ærlighed i små ting er ikke nogen lille ting.

Ehrlichkeit in kleinen Dingen ist kein kleines Ding. Dies war ein gutes Omen. Es passte zu dem, was ich hier sagen wollte. Kleine Dinge spielen eine Rolle. In diesem Buch geht es um bescheidene Belange, deren Wert dennoch beträchtlich ist.

Gott steckt in den Details, sagte der Architekt ​Ludwig Mies van der Rohe. Dieses Zitat erinnert an zeitgenössische Auseinandersetzungen über die Rolle der Architektur bei der Software-Entwicklung und insbesondere in der Agilen Welt. Bob und ich führen gelegentlich heiße Diskussionen über dieses Thema. Und ja, Mies van der Rohe war sehr an der Nützlichkeit und der Zeitlosigkeit der Formen des Bauens interessiert, auf denen großartige Architektur basiert. Andererseits wählte er auch persönlich jeden Türknopf für jedes Haus aus, das er entworfen hatte. Warum? Weil kleine Aufgaben eine Rolle spielen.

Bei unserer laufenden »Debatte« über TDD haben Bob und ich festgestellt, dass wir beide der Auffassung sind, dass die Software-​Architektur eine wichtige Rolle bei der Entwicklung spielt, obwohl wir wahrscheinlich verschiedene Vorstellungen davon haben, was genau das bedeutet. Doch solche Differenzen sind relativ unwichtig, weil wir davon ausgehen können, dass verantwortungsbewusste Profis am Anfang eines Projekts eine gewisse Zeit über seinen Ablauf und seine Planung nachdenken. Die Vorstellungen der späten 1990er-Jahre, dass Design nur durch Tests und den Code vorangetrieben werden könnte, sind längst passé. Doch die Aufmerksamkeit im Detail ist ein noch wesentlicherer Aspekt der Professionalität als Visionen im Großen. Erstens: Es ist die Übung im Kleinen, mit der Profis ihr Können und ihr Selbstvertrauen entwickeln, sich an Größeres heranzuwagen. Zweitens: Die kleinste Nachlässigkeit bei der Konstruktion, die Tür, die nicht richtig schließt, die missratene Kachel auf dem Fußboden oder sogar ein unordentlicher Schreibtisch können den Charme des größeren Ganzen mit einem Schlag ruinieren. Darum geht es bei sauberem Code.

Dennoch bleibt die Architektur nur eine Metapher für die ​​Software-Entwicklung und insbesondere die Phase der Software, in der das anfängliche Produkt etwa in derselben Weise entsteht, wie ein Architekt ein neues Gebäude hervorbringt. In der heutigen Zeit von Scrum und Agile geht es hauptsächlich darum, ein Produkt schnell auf den Markt zu bringen. Die Fabrik soll mit höchster Kapazität Software produzieren. Nur: Hier geht es um menschliche Fabriken, denkende und führende Programmierer, die eine Aufgabenliste abarbeiten oder sich bemühen, anhand von Benutzer-Stories ein brauchbares Produkt zu erstellen. Ein solches Denken wird von der Metapher der Fabrik dominiert. Die Produktionsaspekte der Herstellung von Autos in Japan, also einer von Fließbändern dominierten Welt, haben viele Ideen von Scrum inspiriert.

Doch selbst in der Automobilindustrie wird der Hauptteil der Arbeit nicht bei der Produktion, sondern bei der Wartung geleistet – oder bei dem Bemühen, sie zu vermeiden. Bei der Software werden die 80 oder mehr Prozent unserer Tätigkeit anheimelnd als »Wartung« bezeichnet, ein beschönigendes Wort für »Reparatur«. Statt uns also auf typische westliche Weise auf die Produktion guter Software zu konzentrieren, sollten wir anfangen, eher wie ein Hausmeister bei der Gebäudeinstandhaltung oder wie ein Kfz-Mechaniker bei der Reparatur von Autos zu denken. Was haben japanische Managementweisheiten dazu zu sagen?

Etwa 1951 erschien ein Qualitätsansatz namens ​Total Productive Maintenance (​TPM; »Umfassendes Management des Produktionsprozesses«, der Ausdruck wird nicht ins Deutsche übersetzt) in der japanischen Szene. Er konzentrierte sich weniger auf die Produktion, sondern mehr auf die Wartung. Eine der fünf Säulen des TPM ist der Satz der so genannten 5S-Prinzipien. 5S bezieht sich auf einen Satz von Disziplinen oder Tätigkeitsbereichen. Tatsächlich verkörpern diese 5S-Prinzipien die Bedeutung von ​Lean – einem anderen Modewort in westlichen Produktionskreisen, das zunehmend auch in der Software-Entwicklung verwendet wird. Diese Prinzipien sind nicht optional. Wie Uncle Bob auf der Titelseite sagt, erfordert die Software-Praxis eine gewisse Disziplin: Fokus, Aufmerksamkeit und Denken. Es geht nicht immer nur darum, aktiv zu sein und die Fabrikausrüstung mit der optimalen Geschwindigkeit zu betreiben. Die ​5S-Philosophie umfasst die folgenden Konzepte:

​Seiri oder Organisation (Eselsbrücke: »sortieren«). Zu wissen, wo sich Dinge befinden, ist erfolgsentscheidend. Dazu zählen zum Beispiel Ansätze wie das Vergeben geeigneter Namen. Wenn Sie meinen, die Benennung Ihrer Bezeichner sei nicht wichtig, sollten Sie auf jeden Fall die folgenden Kapitel lesen.

​Seiton oder Ordentlichkeit (Eselsbrücke: »aufräumen«). Ein altes Sprichwort sagt: Ein Platz für alles, und alles an seinem Platz. Ein Code-Abschnitt sollte da stehen, wo Sie ihn zu finden erwarten; und falls er nicht da steht, sollten Sie ein Refactoring von Ihrem Code vornehmen, so dass er danach an der erwarteten Stelle steht.

​Seiso oder Sauberkeit (Eselsbrücke: »wienern«). Sorgen Sie dafür, dass der Arbeitsplatz frei von herumhängenden Drähten, Müllspuren, Einzelteilen und Abfall ist. Was sagen die Autoren hier über die Vermüllung Ihres Codes mit Kommentaren und auskommentierten Codezeilen, die den Verlauf der Entwicklung oder Wünsche für die Zukunft wiedergeben? Weg damit.

​Seiketsu oder Standardisierung. Die kommt zu einem Konsens darüber, wie der Arbeitsplatz sauber gehalten werden soll. Hat dieses Buch etwas über einen konsistenten Codierstil und gemeinsam in der Gruppe befolgte Praktiken zu sagen? Wo kommen diese Standards her? Lesen Sie weiter.

​Shutsuke oder Disziplin (Selbst-disziplin). Dies bedeutet, die Disziplin aufzubringen, den Praktiken zu folgen, seine Arbeit regelmäßig zu überdenken und bereit zu sein, sich zu ändern.

Wenn Sie die Herausforderung – jawohl, die Herausforderung – annehmen, dieses Buch zu lesen und anzuwenden, werden Sie den letzten Punkt verstehen und schätzen lernen. Hier kommen wir schließlich zu den Wurzeln einer verantwortlichen professionellen Einstellung in einem Beruf, der sich um den Lebenszyklus eines Produktes kümmern sollte. So wie Automobile und andere Maschinen unter TPM vorbeugend gewartet werden, sollte eine Wartung im Falle eines Zusammenbruchs – also darauf zu warten, dass die Bugs sich zeigen – die Ausnahme sein. Stattdessen sollten Sie eine Ebene höher ansetzen: Inspizieren Sie die Maschinen jeden Tag und tauschen Sie Verschleißteile aus, bevor sie kaputtgehen, oder lassen Sie den sprichwörtlichen Ölwechsel vornehmen, um die Abnutzung des Motors möglichst zu verringern. Für Ihren Code bedeutet das: Nehmen Sie ein gnadenloses Refactoring vor. Sie können mit der Verbesserung noch eine Ebene höher ansetzen, wie es die TPM-Bewegung innovativ vor über 50 Jahren vorgemacht hat: Bauen Sie Maschinen, die von vornherein wartungsfreundlicher sind. Code lesbar zu machen, ist genauso wichtig, wie ihn ausführbar zu machen. Die ultimative Praxis, die in TPM-Kreisen etwa 1960 eingeführt wurde, besteht darin, die alten Maschinen vorbeugend durch vollkommen neue zu ersetzen. Wie Fred ​Brooks anmahnt, sollten wir wahrscheinlich Hauptteile unserer Software etwa alle sieben Jahre von Grund auf erneuern, um die schleichende Ansammlung von ​Cruft (Jargon: Müll, Staub, Unrat) zu beseitigen. Vielleicht sollten wir die von Brooks genannte Zeitspanne drastisch reduzieren und nicht von Jahren, sondern von Wochen, Tagen oder gar Stunden sprechen. Denn dort finden sich die Details.

​​Details haben eine mächtige Wirkungskraft. Dennoch hat dieser Ansatz etwas Bescheidenes und Grundsätzliches, so wie wir es vielleicht stereotyp von einem Ansatz erwarten, der japanische Wurzeln für sich in Anspruch nimmt. Aber dies ist nicht nur eine köstliche Art, das Leben zu sehen. Auch die westliche Volksweisheit enthält zahlreiche ähnliche Sprichwörter. Das Seiton-Zitat von oben floss auch aus der Feder eines Priesters in Ohio, der Ordentlichkeit buchstäblich »als Gegenmittel für jede Art von Bösem« sah. Was ist mit Seiso? Sauberkeit kommt gleich nach Göttlichkeit. So schön ein Haus auch sein mag, ein unordentlicher Tisch raubt ihm seinen ganzen Glanz. Was bedeutet Shutsuke in diesen kleinen Dingen? Wer an wenig glaubt, glaubt an viel. Wie wär’s damit, das Refactoring des Codes rechtzeitig durchzuführen, um seine Position für folgende »große« Entscheidungen zu stärken, als die Aufgabe aufzuschieben? Ein Stich zur rechten Zeit erspart dir neun weitere. Wer früh kommt, mahlt zuerst. Was du heute kannst besorgen, das verschiebe nicht auf morgen. (Dies war die ursprüngliche Bedeutung des Ausdrucks »der letzte tragbare Moment« bei Lean, bevor er in die Hände von Software-Beratern fiel.) Was ist mit der Ordnung eines Arbeitsplatzes im Kleinen im Vergleich zum großen Ganzen? Auch die größte Eiche wächst aus einer kleinen Eichel. Oder wie ist es damit, einfache vorbeugende Arbeiten in den Alltag einzubauen? Vorsicht ist besser als Nachsicht. Ein Apfel am Tag hält den Doktor fern. Sauberer Code anerkennt die verwurzelte Weisheit unserer Kultur im Allgemeinen, oder wie sie einmal war, oder wie sie sein sollte, oder wie sie sein könnte, indem er den Details die schuldige Aufmerksamkeit schenkt.

Selbst in der Literatur über große Architektur greifen Autoren auf Sprichwörter über die Bedeutung von Details zurück. Denken Sie an die Türgriffe von Mies van der Rohe. Das ist Seiri. Das bedeutet, sich um jeden Variablennamen zu kümmern. Sie sollten Variablennamen mit derselben Sorgfalt auswählen wie den Namen eines erstgeborenen Kindes.

Jeder Hausbesitzer weiß, dass eine solche Pflege und fortwährende Verbesserung niemals zu Ende ist. Der Architekt Christopher Alexander – Vater der Patterns und Pattern-Sprachen – betrachtet jeden Design-Akt selbst als einen kleinen, lokalen Akt der Reparatur. Und er betrachtet die Anwendung des Könnens auf feine Strukturen als den einzigen legitimen Arbeitsbereich des Architekten; die größeren Formen können den Patterns und deren Anwendung durch die Bewohner überlassen werden. Design geht immer weiter. Es betrifft nicht nur den Anbau neuer Räumlichkeiten, sondern auch profanere Aufgaben wie ein neuer Anstrich, das Ersetzen eines abgelaufenen Teppichs oder die Modernisierung der Spüle in der Küche. In den meisten Künsten werden ähnliche Überzeugungen vertreten. Bei unserer Suche nach anderen, die das Haus Gottes in den Details sehen, stießen wir beispielsweise auf den französischen Autor Gustav Flaubert aus dem 19. Jahrhundert. Der französische Dichter Paul Valery sagt uns, ein Gedicht wäre niemals fertig und müsse laufend überarbeitet werden; mit dieser Arbeit aufzuhören wäre vergleichbar damit, dieses Gedicht zu verwerfen. Eine solche Besessenheit von Details ist allen Bemühungen gemeinsam, die auf Exzellenz, also auf herausragende Leistungen gerichtet sind. Also: Vielleicht gibt es hier wenig Neues, aber wenn Sie dieses Buch lesen, werden Sie herausgefordert, die guten Disziplinen wieder aufzunehmen, die Sie vor langer Zeit aus Apathie, dem Wunsch nach Spontanität oder einfach deswegen aufgegeben haben, weil Sie »etwas anderes« machen wollten.

Leider betrachten wir solche Überlegungen normalerweise nicht als Grundbausteine der Kunst der Programmierung. Wir entlassen unseren Code früh aus unserer Obhut, nicht, weil er fertig ist, sondern weil unser Wertesystem mehr auf die äußere Erscheinung als auf die Substanz des gelieferten Produkts gerichtet ist. Diese fehlende Aufmerksamkeit kommt uns letztendlich teuer zu stehen: Irgendwann machen sich die Defekte immer bemerkbar. Weder in akademischen Kreisen noch in der Industrie begibt sich die Forschung in die niedrigen Ebenen hinunter, Code sauber zu halten. Früher, als ich noch bei der Bell Labs Software Production Research Organization (also wirklich Produktion!) beschäftigt war, machten wir die beiläufige Entdeckung, dass ein konsistenter Stil beim Einrücken von Klammern der statistisch signifikanteste Indikator für eine geringe Fehlerhäufigkeit war. Wir wollen, dass die Architektur, die Programmiersprache oder irgendein anderes hoch angesiedeltes Konzept die Ursache für Qualität sein soll. Als Entwickler, deren vorgebliche Professionalität auf der Meisterung von Werkzeugen und abgehobenen Design-Methoden basiert, fühlen wir uns von dem Mehrwert beleidigt, den diese Maschinen aus der Fabrikhalle, pardon!, Codierer, erzielen, indem sie einfach einen bestimmten Stil der Einrückung von Klammern konsistent anwenden. Um mein eigenes Buch zu zitieren, das ich vor 17 Jahren geschrieben habe: Ein solcher Stil unterscheidet Exzellenz von bloßer Kompetenz. Die japanische Weltsicht versteht den entscheidenden Beitrag jedes gewöhnlichen Arbeiters und mehr noch, wie Entwicklungssysteme von den einfachen gewöhnlichen Aktionen dieser Arbeiter abhängen. Qualität ist das Ergebnis eine Million selbstloser Akte der Sorgfalt – nicht nur das einer großartigen Methode, die vom Himmel gefallen ist. Dass diese Akte einfach sind, bedeutet nicht, dass sie simplizistisch (einfältig) sind. Es bedeutet auch nicht, dass sie leicht sind. Dennoch sind sie der Stoff, aus dem die Größe und mehr noch die Schönheit menschlicher Anstrengungen gemacht ist. Wer diese Akte ignoriert, hat noch nicht sein volles menschliches Potenzial realisiert.

Natürlich befürworte ich immer noch, auch den größeren Rahmen zu betrachten und besonders den Wert von architektonischen Ansätzen zu berücksichtigen, die in einem tiefen Wissen sowohl des Problembereiches als auch der Software-Usability verwurzelt sind. Doch darum geht es in diesem Buch nicht – zumindest nicht vordergründig. Dieses Buch will eine subtilere Botschaft verbreiten, deren Gewichtigkeit nicht unterschätzt werden sollte. Sie passt zu dem gegenwärtigen Credo wirklich codebasierter Entwickler wie Peter Sommerlad, Kevlin Henney und Giovanni Asproni. Ihre Mantras lauten: »Der ​Code ist das ​Design« und »Einfacher Code«. Während wir darauf achten müssen, dass die Schnittstelle das Programm ist und dass ihre Struktur viel über die Struktur unseres Programmes aussagt, ist es von erfolgsentscheidender Bedeutung, dass wir uns laufend mit der bescheidenen Einstellung identifizieren, dass das Design tatsächlich nur im Code existiert. Und während eine Überarbeitung in der Metapher der fabrikmäßigen Produktion zu höheren Kosten führt, führt sie beim Design zu einem Mehrwert. Wir sollten unseren Code als den wunderschönen Ausdruck edler Design-Anstrengungen betrachten – Design als Prozess, nicht als statischer Endpunkt. Nur im Code lassen sich letztlich die architektonischen Metriken der Kopplung und Kohäsion nachweisen. Wenn Larry ​Constantine Kopplung und Kohäsion beschreibt, spricht er von Code – nicht von abgehobenen abstrakten Konzepten, die man vielleicht in UML findet. Richard ​Gabriel rät uns in seinem Essay Abstraction Descant, Abstraktion sei böse. Code ist anti-böse, und sauberer Code ist vielleicht göttlich.

Zurück zu meiner kleinen Packung Ga-Jol: Ich glaube, dass es wichtig ist, anzumerken, dass uns die dänische Weisheit nicht nur rät, unsere Aufmerksamkeit auf die kleinen Aufgaben zu lenken, sondern auch, bei kleinen Aufgaben ehrlich zu sein. Dies bedeutet, wir müssen dem Code gegenüber ehrlich sein, wir müssen unseren Kollegen gegenüber über den Zustand unseres Codes ehrlich sein und vor allem, wir müssen uns selbst gegenüber über den Zustand unseres Codes ehrlich sein. Haben wir unser Bestes gegeben, um den »Campingplatz sauberer zu hinterlassen, als wir ihn gefunden haben«? Haben wir das Refactoring des Codes erledigt, bevor wir ihn eingecheckt haben? Dies sind keine nebensächlichen Belange, sondern Belange, die zum Kern agiler Werte gehören. Zum Beispiel empfiehlt ​Scrum, das Refactoring zu einem Bestandteil des Konzepts »Done« (»Fertig«) zu machen. Weder Architektur noch sauberer Code verlangt nach Perfektion, sondern nur nach Ehrlichkeit und dem Bemühen, unser Bestes zu geben. Irren ist menschlich, vergeben göttlich. Bei Scrum machen wir alles sichtbar. Wir zeigen unsere schmutzige Wäsche. Wir sind ehrlich über den Zustand unseres Codes, weil Code niemals perfekt ist. Wir werden menschlicher, werden würdiger, das Göttliche zu empfangen, und nähern uns der Größe in den Details.

In unserem Beruf brauchen wir verzweifelt alle Hilfe, die wir bekommen können. Wenn ein sauberer Fabrikboden die Anzahl der Unfälle reduziert und wohlgeordnete Werkzeugkästen die Produktivität verbessern, dann kann man dies nur befürworten. Was dieses Buch angeht: Es ist die beste pragmatische Anwendung von Lean-Prinzipien auf Software, die ich je in Druckform gesehen habe. Aber weniger hatte ich von dieser praktischen kleinen Gruppe denkender Individuen auch nicht erwartet, die sich nicht nur seit Jahren darum bemühen, immer besser zu werden, sondern auch ihr Wissen an die Branche weiterzugeben. Dieses Buch ist ein Ausdruck dieses Bemühens. Es hinterlässt die Welt ein wenig besser, als ich sie vorfand, bevor Uncle Bob mir das Manuskript schickte.

Doch genug von meinen abgehobenen Einsichten. Ich muss meinen Schreibtisch aufräumen.

James O. Coplien

Mørdrup, Dänemark

Einführung

Abb. 1:Abdruck mit freundlicher Genehmigung von Thom Holwerda (http://www.osnews.com/story/19266/WTFs_m)

Welche Tür repräsentiert Ihren Code? Welche Tür repräsentiert Ihr Team oder Ihr Unternehmen? Warum sind wir in diesem Raum? Geht es nur um einen normalen Code-Review oder haben wir eine Reihe schrecklicher Probleme gefunden, die kaum geringer als das Leben sind? Debuggen wir in Panik; brüten wir über Code, der unserer Meinung nach funktionieren sollte? Laufen uns die Kunden in Scharen davon und hängen uns die Manager im Nacken? Wie können wir dafür sorgen, dass wir hinter der richtigen Tür landen, wenn es heiß hergeht? Die Antwort ist: .

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!