Clean Code

Clean Code beginnt lange vor dem Codieren. Clean Code ist mehr als nur ein gewisser Umgang mit Code.

Clean Code Development darf den Kontext nicht vernachlässigen, soll im Rahmen der Agilität stattfinden und braucht eine eigene Systematik.

Das hört sich so gar nicht nach dem an, was Sie nach Lektüre des Buches “Clean Code” von Robert C. Martin oder dem Besuch der Seite clean-code-developer.de erwartet hätten? Keine Sorge, es passt alles zusammen.

Kontext

Darstellungen wie die in “Clean Code” von Robert C. Martin oder “The Art of Readable Code” von Dustin Boswell haben ihren Wert – doch letztlich greifen Sie unserer Ansicht nach zu kurz. Sie reduzieren ein tiefgreifendes Problem der Softwareentwicklung auf vor allem ein Artefakt: die textuelle Form einer Lösung, Code.

Doch wie kommt es dazu, dass “irgendetwas” mit dem Code nicht so ist, wie es sein sollte, dass es hakt und knirscht bei der Softwareentwicklung?

Schon im Rahmen unserer Clean Code Developer Initiative (clean-code-developer.de) haben wir versucht, den Blick zu weiten. Prinzipien und Praktiken sind wichtig, doch letztlich sind auch sie Kinder ihrer Zeit und müssen angepasst werden können. Deshalb haben wir Clean Code auf ein Fundament aus Werten gestellt:

  • Wandelbarkeit
  • Korrektheit
  • Produktivität
  • Kontinuierliche Verbesserung

Sie weisen darauf hin, dass Clean Code “nur” ein Mittel ist, um in einem gewissen Kontext ein Ziel zu erreichen. Clean Code ist kein Selbstzweck. Deshalb ist auch immer wieder zu überprüfen, welche Prinzipien und Praktiken und Techniken und Technologien den eigentlichen Zweck am besten erfüllen.

Und was ist der Zweck von Clean Code? Er dient der Erfüllung von mehreren, oft unausgesprochenen Anforderungen des Kunden. Das ist wichtig zu verstehen, denn sonst bleibt unklar, wie Clean Code finanziert werden soll.

Unserer Auffassung nach ist es zentral für den Erfolg jeder Clean-Code-Maßnahme, sie im Kontext der anderen grundsätzlichen Anforderungen des Kunden an eine Software zu sehen. Das, was Clean Code Development (CCD) erreichen soll – insb. Wandelbarkeit und Korrektheit -, muss stets in Balance sein mit den Anforderungen an Funktionalität und Effizienz. Clean Code ist nicht wichtiger als funktionaler oder performanter Code – aber auch nicht unwichtiger.



Zu dieser “Gleichberechtigung”, dieser Balance möchten wir mit unserer Methode des Clean Code Development beitragen. Dazu gehört auch, dass wir die Entstehung von Clean Code in einem Entwicklungsprozess betrachten.

Clean Code Development heute ist insofern auch mehr als das, was wir 2009 im Rahmen der Clean Code Developer Initiative zusammengetragen hatten. Inzwischen hat sich die Welt und unser Verständnis weitergedreht. Die dortigen Bausteine sind immer noch relevant – doch um sie herum fehlt einiges. Schwerpunkte haben sich verschoben, neue sind hinzugekommen. Auch Clean Code Development selbst unterliegt einem Wandel.

Clean Code Development kann daher nur in einem grundsätzlich agilen Rahmen stattfinden.

Agilität

Clean Code Development ist notwendigerweise agile Softwareentwicklung. Agilität reduziert auf das Wesentliche ist:

  • inkrementell
  • lernend
  • reaktiv

In diesem Rahmen soll aber nicht nur funktionaler und effizienter Code entstehen, sondern eben auch wandelbarer und korrekter. Clean Code Development ist für uns ohne eine Systematik, wie er inkrementell und eng am Kunden hergestellt werden kann, nicht denkbar.

Unser Ansatz beschreibt daher einen klaren Weg, wie Entwickler innerhalb eines agilen Inkrements sich schrittweise sauberem Code annähern. Wir nennen es “den Anforderungen-Logik-Graben überbrücken”:

Denn hier bleibt die traditionelle Agilität von XP über Scrum bis Kanban eine Antwort schuldig: Wie soll eigentlich aus natürlichsprachlichen Anforderungen des Kunden eine formalsprachliche Lösung entwickelt werden?

Anforderungen in Use Cases und User Stories zu zerlegen (Inkremente) und das immer wieder zu tun (Iterationen), ist eine wichtige Voraussetzung für hohe Produktivität und Minimierung von Verschwendung durch Sackgassen und Umwege. Doch fein geschnittene Anforderungen allein geben Entwicklern noch nicht genügend Guidance, um aus ihnen Code, d.h. vor allem Verhalten erzeugende Logik abzuleiten, gar Clean Code.

Dazu bedarf es vielmehr ganz spezifischer Methoden für die unverbrüchlichen Phasen der Programmierung: Analyse, Entwurf und Implementation.

Unverbrüchlich sind diese Phasen, weil es ohne sie schlicht nicht geht. Ob agiler Softwareentwickler, ob Software Engineer oder Software Craftsman: unabhängig vom Weltbild und Rollenverständnis lässt sich Code nicht implementieren, wenn nicht vorher eine “Idee” von der Lösung (Lösungsansatz) entwickelt (Entwurf) und vor dieser nicht ein solides Verständnis der Anforderungen hergestellt wurde (Analyse).

Das passiert auch immer – nur leider passiert es gewöhnlich in einer Weise, die Wandelbarkeit und Korrektheit nicht zuträglich ist.

Hier setzt unsere Methode des Clean Code Development an. Clean Code braucht ein vorgelagertes Clean Design, das wiederum auf einer Clean Analysis aufsetzt. Und dazu braucht es ein ganzheitliches Rahmenwerk, in dem die unterschiedlichen Aspekte der Softwareentwicklung zusammenkommen.

Systematik

Clean Code, Clean Design, Clean Analysis, überhaupt ein sauberer Umgang mit allen Anforderungen bedeutet für uns, dass systematisch explizite Strukturen entstehen.

Code ohne Strukturen erfüllt lediglich und im besten Fall funktionale Anforderungen mittels programmiersprachlicher Anweisungen (Logik). Wenn es jedoch noch ein bisschen mehr sein darf, wenn auch noch Effizienz (z.B. Performance, Skalierbarkeit, Sicherheit) oder Korrektheit oder Wandelbarkeit oder Produktivität (im Sinne häufigen Feedbacks) geliefert werden sollen… wenn also auch nicht-funktionale Anforderungen erfüllt werden sollen, dann muss Struktur her.

Strukturieren bedeutet, dass “rohe Logik” zweckvoll zusammengefasst und in Beziehung gesetzt wird. Verschiedene Zwecke erfordern dabei verschiedene Strukturen. Das bedeutet unserer Auffassung nach, dass Software gleichzeitig in mehreren Dimensionen strukturiert werden muss, um gleichzeitig und in Balance Anforderungen ganz unterschiedlicher Kategorien zu erfüllen.

All diese Dimensionen zusammen nennen wir das Softwareuniversum. In ihm kann jede Aktivität der Entwicklung und jede Struktur einer Software verortet werden:

Die zumeist in der Diskussion stehende Struktur ist die zur Erfüllung von Effizienz-Anforderungen. Das ist für uns die Host-Dimension. Die Rolle des Softwarearchitekten ist vor allem mit ihr beschäftigt. Dort brodelt es auch ständig in Bezug auf Technologien.

Ein Effekt dieses Fokus ist, dass Strukturen für die Wandelbarkeit weniger, sogar deutlich weniger Aufmerksamkeit bekommen. Und so entsteht oft schneller als gedacht Legacy Code, ein Big Ball of Mud oder einfach nur der gute alle Spaghetticode. Wandelbarkeit liegt sozusagen im blinden Fleck der Softwareentwicklung. Doch auch und gerade sie braucht gute Strukturen. Die werden aus Modulen hergestellt.

Leider ist das nicht so einfach, wie der Begriff “Modul”, der in aller Munde ist, suggeriert. Deshalb konzentrieren sich unsere Trainings zu einem guten Teil auf diese Dimension des Softwareuniversums.

Hosts definieren eine Laufzeitstruktur für Software, Module eine Lebenszeitstruktur. Die Slice-Dimension hingegen bezieht sich auf die Entwicklungszeit bzw. das agile Vorgehen. Slices strukturieren Software gegenüber dem Kunden. Sie stellen Inkremente dar. Mit ihnen wird die Domäne zerlegt. Was der Kunde als wertvoll bzw. als Einheit identifiziert hat, soll im Code auch als Strukturelement identifizierbar erhalten bleiben.

Impulse für Slice-Struktur geben Use Cases und User Stories. Im Slicing werden die jedoch weiter zerschnitten, um schneller durch die Phasen Entwurf und Implementation hin zu Feedback zu kommen.

Clean Code Development hat also Einfluss auf den Prozess. Dessen Iterationsfrequenz wird bewusst erhöht, um Clean-Code-Praktiken quasi unvermeidbar zu machen. Das ist eine Notwendigkeit, um aus der bisherigen Praxis der Entschuldigung unsauberen Codes herauszukommen.

Funktionale Anforderungen finden schließlich ihre Struktur in so genannten Flows. Ihre Strukturelemente werden zu unterschiedlich umfangreichen funktionalen Einheiten in Datenflüssen zusammengefasst.

Diese Dimension steht bewusst in einer Linie mit der Domänenzerlegung, denn sie ist deren Fortführung “hinter der Fassade” dessen, was der Kunde sieht und beurteilen kann.

Zusammen mit der Host-Dimension erfüllt die Flow-Dimension die Laufzeitanforderungen des Kunden.

Das Softwareuniversum bindet für uns zusammen, was ansonsten in der Softwareentwicklung meist für sich steht. Im Softwareuniversum können wir aber nicht nur Clean Code Development verorten, sondern auch erklären, welche Rollen Softwarearchitekten oder Product Owner spielen, wir können Entwicklungen wie Actor Frameworks oder Microservices zuordnen und nicht zuletzt lassen sich die ehrwürdige Objektorientierung, Entwurfsmuster oder die SOLID-Prinzipien auf einen Platz verweisen.

Flow-Design

Wenn Sie Clean Code suchen und im Softwareuniversum eine Dimension Flows finden, dann mag Sie das verwundern. Was sollen erstens solche visuellen Darstellungen (s.u.) und zweitens Datenflüsse mit sauberem Code zu tun haben?

Wir haben bei Start der Clean Code Developer Initiative 2009 auch nicht gedacht, dass es einmal dazu kommen würde. Doch in den darauffolgenden Jahren ist uns immer klarer geworden:

  1. Ohne einen visuellen Entwurf bleiben Clean-Code-Anstrengungen auf halber Strecke stecken.
  2. Ohne eine Abkehr von tiefen Abhängigkeitsbäumen bleiben Code-Säuberungen oberflächlich.

Clean Code braucht das ganze Team. Einzelne können nur sehr begrenzt etwas ausrichten, um Code sauber zu halten. Wie aber kann ein ganzes Team über Code, nein, über Software nachdenken und reden? Das funktioniert mit Worten nur sehr umständlich. Eine visuelle Sprache ist nötig. UML wollte das sein, doch UML ist aus unserer Sicht gescheitert. Nur ca. 5-10% der Entwickler benutzen UML überhaupt – und das trotz breiter Unterrichtung darüber in allen Medien. Unsere Diagnose: UML eignet sich nicht zur Entwicklung (!) von Software. Sie mag etwas bieten für die Dokumentation von Software, doch auf dem Weg dahin von den Anforderungen ist UML kaum hilfreich.

Aber nur, weil UML in dieser Hinsicht gescheitert ist, bedeutet das nicht, dass Entwurf von Software im Allgemeinen, also das Nachdenken vor der Codierung, und visueller Entwurf im Speziellen überflüssig wären. Das Gegenteil ist der Fall. Sie sind nötiger denn je. Aus dem Grund haben wir viel Mühe darauf verwandt, eine leichtgewichtige und praktikable visuelle Notation zu entwickeln, um über Softwarelösungen nachdenken und reden zu können, bevor Code existiert.

So ein Entwurf ist für Sie ohne weitere Information sicher verwirrend oder scheint gar kontraproduktiv. Doch glauben Sie uns: Schon nach wenigen Übungen im Flow-Design erkennen Sie den Wert. Der liegt in der Möglichkeit, mentale Modelle ad hoc für sich und andere darstellen zu können. So wird Überblick erzeugt. Das beschleunigt die Kommunikation. Aus umständlichen Worten und schwammigen Gesten werden konkrete Funktionseinheiten.

Und diese Funktionseinheiten sind so verbunden, dass sie eine Ursache für unverständlichen und schwer wandelbaren und schwer testbaren Code vermeiden: funktionale Abhängigkeiten.

Visueller Entwurf ist dabei bewusst skizzenhaft. Nur so wird die Flexibilität im Denken bewahrt, die bei der kreativen Lösungsentwicklung nötig ist. Entwürfe sind keine Dokumentationen. Sie sollen auch nicht (ohne weiteres) von Entwicklern verstanden werden, die nicht bei ihrer Erarbeitung anwesend waren. Flow-Design Entwürfe sind verwandt mit Graphic Recordings. Sie reduzieren Komplexität. Was vorher im Kopf verflochten war, ist während des Flow-Designs klar vor jedermanns Augen.

Flow-Design mit seinen Datenflüssen scheint eine Abkehr von der viel gerühmten Objektorientierung, ist es aber nicht. Vielmehr besinnt sich Flow-Design auf die Wurzeln der Objektorientierungen, in dem es das, was ihrem Erfinder Alan Kay am wichtigsten war, in den Vordergrund rückt: die Nachrichtenorientierung (engl. messaging).

Flow-Design ist Objektorientierung mit Fokus auf Verhalten. Denn Verhalten zählt für den Kunden am meisten. Er möchte, dass Software auf Input funktional und effizient reagiert.

Um das sicherzustellen und gleichzeitig die Wandelbarkeit und Korrektheit nicht aus den Augen zu verlieren, nimmt Flow-Design eine wichtige Stelle in unseren Clean Code Developer Trainings ein. Schon vor dem Codieren können wir dadurch auch die Einhaltung von Prinzipien fördern, wie sie bei clean-code-developer.de zusammengetragen sind. Und ausgehend davon können wir viel leichter Software in den Dimensionen Module und Hosts entfalten.

Clean Code ohne expliziten, deklarativen Entwurf mit Flow-Design ist für uns nicht mehr denkbar – auch wenn das in der Clean-Code-Bibel so nicht drin steht.

Kein traditioneller Ansatz

Clean Code wird weithin so verstanden und vermittelt, wie es Robert C. Martin in seinem Buch “Clean Code” beschrieben hat. Werfen Sie die Suchmaschine Ihrer Wahl an und stöbern Sie zum Begriff Clean Code und Sie werden auf Single Responsibility bzw. SOLID, Namenskonventionen, Methodenlänge, Root Cause Analysis, Code Metriken, Codeguidelines, sogar Entwurfsmuster und vieles mehr stoßen.

Das ist auch alles gut und richtig und passend. Wir selbst haben im Wiki der Clean Code Developer Initiative für diese Sichtweise auf das Thema plädiert und versucht, sie einfacher verdaubar zu machen mit Werten, Tugenden und Armbändchen.

Dazu stehen wir auch weiterhin. Diese Inhalte finden sich zu einem guten Teil deshalb auch in unseren Ausbildungsangeboten und offenen Trainings. Allerdings haben wir seit dem Erscheinen des Buches und dem Aufsetzen der Initiative neue Erkenntnisse gewonnen. Wir sind nicht stehengeblieben.

Zwei zentrale Einsichten wollen wir herausheben, die sich in Form und Inhalt deutlich in unseren Angeboten widerspiegeln:

  • Clean Code Development braucht eine Methode, einen Rahmen, eine Guideline, eine Systematik. Es ist nicht damit getan, nützliche Prinzipien und Praktiken in der einen oder anderen Reihenfolge und Gruppierung “abzuhaken”. “20 Minuten + 1 Übung zum Thema SRP? Check! 15 Minuten + 1 Übung zum Thema Methodenlänge? Check!” usw. usf. funktioniert nicht. Wie gesagt, das sind alles relevante Aspekte von Clean Code, doch sie in einer Abfolge kennenzulernen, wie sie im Buch stehen oder in traditionellen Trainings vermittelt werden, wird nur wenig Wirkung auf den Arbeitsalltag haben, weil darin keine Systematik steckt. Es fehlt der Zusammenhang, der Kontext. Das haben wir bei unseren ersten Training in den Jahren 2009 und 2010 bemerkt und nachgebessert. Über die Jahre ist daraus die Methode entstanden, die die CCD School heute vermittelt. Sie ist kohärent und umfassend. Sie nimmt den Entwickler vom ersten Kontakt mit Anforderungen an die Hand und führt ihn bis zur Ablieferung von Code. SRP & Co haben darin ihren Platz, doch sie sind bei weitem nicht alles.
  • Clean Code Development braucht Begleitung. Mit einer einmaligen “Vorlesung” von 2, 3 oder auch 5 Tagen ist es nicht getan. Egal, welcher Stoff vermittelt wird – nur CCD Bausteine oder auch eine Methode -, er muss geübt werden. Und wieder geübt werden. Und nochmal geübt werden. Das ist beim Selbststudium sehr schwer. Das findet in Trainings natürlich statt, doch ist die Zeit dafür begrenzt, weil ja auch noch weiterer Stoff vermittelt werden soll. Also muss das Üben am Arbeitsplatz fortgeführt werden. Dazu kommt es jedoch kaum, weil nach dem Training der Projektalltag mit all seinen Dringlichkeiten wieder zuschlägt. Aus diesem Grunde haben wir unsere Ausbildungen vor einigen Jahren umgestellt. Es gibt keine “Druckbetankungen” mehr. Mit nur einem Termin für Stoffvermittlung+Übungen ist es nicht getan. So ist zwar das Format offener Trainings, doch die stellen aus unserer Sicht ja keine Ausbildung dar. Ausbildung braucht Wiederholung und Begleitung. Während einer Ausbildung wollen wir die Teilnehmer nicht nur einmal sehen, sondern mehrfach im Abstand von einigen Wochen. Zwischen diesen Terminen sollen die Teilnehmer sich selbstständig mit dem Lehrstoff beschäftigen. Dafür geben wir Ihnen spezielle Aufgaben und schauen auch Zwischenresultate bis zum nächsten gemeinsamen Termin an. Durch solche Begleitung wird einerseits der Stoff vertieft, andererseits wird aber auch geübt, eben selbstständig zu lernen, d.h. Zeit fürs Lernen in den Wirren des Arbeitsalltags konsequent freizuschaufeln. Für uns ist das eine Voraussetzung, wenn der Transfer des Lehrstoffes in den Alltag gelingen soll.

Bei Clean Code Development geht es um nichts Geringeres als die Zukunftsfähigkeit von Software und damit von Unternehmen. Wenn die bisher so wenig im Blick war, dass Berge an legacy code und big balls of mud entstanden sind, dann ist ein Richtungswechsel nicht durch Abarbeiten einer Checkliste von Prinzipien und Praktiken in einem Training mit einem Termin zu erwarten.

Die Gewohnheiten, die ins brownfield geführt haben, sitzen tief – nicht nur in Entwicklern, sondern im ganzen Unternehmen. Deshalb bedarf es eines Schulungsansatzes, der in Form und Inhalt darauf zugeschnitten ist. Mit den Ausbildungen der CCD School bieten wir einen solchen Ansatz. Sie sind umfassend, kongruent, modern.