Uncle Bob hat “crap code” den Kampf angesagt: “Craftsmanship over Crap” – zünftige Handwerksleistung soll für mehr Qualität in der Softwareentwicklung sorgen. Dagegen hat Nicolai Josuttis vor einigen Jahren den Gedanken geäußert, wir sollten endlich lernen, uns mit “crap code” abzufinden; er sei nicht zu vermeiden:
“So, when I say "Welcome Crappy Code", my point is not to force crappy code. My point is simply to face the reality. But, yes, you can consider my position as a view of resignation.”
Natürlich habe ich mich gegen eine solche Resignation gewendet. Nicht umsonst habe ich die Clean Code Developer Initiative mitgegründet. Ja, wir können “crappy code” aus der Welt schaffen! Wir müssen uns nur bemühen. CCD macht´s möglich.
Nun sind seitdem zwei Jahre vergangen und ich sehe die Welt ein wenig anders.
Es gibt viel Motivation in der Entwicklergemeinde, nicht länger “crap code” zu entwickeln. Die Zahl der Mitglieder in der CCD XING-Gruppe wächst ungebrochen. Das ist toll.
Ich glaube auch weiterhin daran, dass wir schlechte Qualität nicht fatalistisch hinnehmen sollten. Teams müssen besseren Code schreiben, wenn sie im Geschäft bleiben wollen. Und wir haben auch grundsätzlich die Kenntnisse, wie das geht, besseren Code zu schreiben.
Aber… ja, ich sehe da ein Aber. Der geballten Faust in der Tasche der Entwicklerschaft steht eine ökonomische und organisatorische und kognitive Macht gegenüber, die nicht zu vernachlässigen ist.
Softwarequalität (also innere Softwarequalität vor allem im Sinne von Korrektheit und Evolvierbarkeit) ist nur ein Wert unter vielen. So wie Ehrlichkeit auch nur ein Wert unter vielen ist.
Wo es aber ein Wertesystem gibt, also viele, auch noch konkurrierende Werte, da müssen Werte ausbalanciert werden. Wie in der Produktion muss das Optimum beim Ganzen eingestellt werden und nicht beim Teil.
Schon das bedeutet, dass wir nie zu optimaler innerer Qualität kommen werden. Sie wäre ein lokales Optimum, unter dem das Ganze leiden würde.
Dazu kommt, dass wir nicht einmal optimale Qualität herstellen könnten, wenn wir wollten. Wir verhalten uns in Bezug auf innere Softwarequalität nicht rational. Denn rational wäre, unsere Begrenzung durch Kosten bei ihrer Herstellung zu akzeptieren und danach abzuwägen.
Wir können nicht einmal rational entscheiden, weil neben ökonomischen und organisatorischen Gründen auch kognitive Gründe unsere Entscheidungen beschränken. Ich behaupte, dass wir nicht einmal wissen können, was die optimale Qualität wäre. Kein noch so langes Nachdenken und Diskutieren darüber würde uns zu einer eindeutigen Lösung bringen. Der Grund dafür liegt in der Volatilität der Anforderungen. In einer kleinen Serie zu den Gesetzen der Softwareentwicklung hatte ich dazu schon einmal etwas gesagt.
Es geht also nicht. Verabschieden wir uns von der Vorstellung hohe oder gar optimale innere Qualität herzustellen. Wir bewegen uns nicht im Bereich der Rationalität, sondern müssen unter Bedingungen Beschränkter Rationalität (Bounded Rationality) arbeiten.
Unser Ziel kann eingebunden in ein Netz von Werten nur eine genügend gute innere Softwarequalität sein. Wir müssen uns mit “good enough” bescheiden. Auf allen Ebenen: bei der Architektur, bei der Modellierung, bei der Implementierung. Immer kriegen wir nur “good enough” hin. Das sehe ich als Annäherung an Nicolais Standpunkt.
Also: Mehr Qualität, ja! Aber den Anspruch an die Qualität begrenzen.
Das bedeutet zum Beispiel, wir können uns das ganze Gerede über Eleganz sparen. Eleganz ist etwas für Leute mit viel Zeit. Eleganz ist Verfeinerung. Und damit gewinnt man keine Schlacht.
Ebenso können wir uns längliche Diskussionen über alle Prinzipien von Clean Code Developer sparen. Sollte die Methode auf dieser Klasse oder jener definiert sein, damit das SRP eingehalten wird? Solche Fragen müssen ohne Zweifel erörtert werden – doch am besten in einer Timebox. Wenn darüber nach 10 Minuten keine Einigung mit Argumenten erzielt werden kann, dann sollte der Code so bleiben, wie er ist. Die Zukunft wird zeigen, wer in der Diskussion Recht hatte.
Die Prinzipien und Praktiken von Clean Code Developer behalten ihren Wert – aber nun sehe ich noch eine Herausforderung, die darüber hinausgeht:
Wie kommen wir möglichst schnell zu einer “good enough” Softwarequalität? Eine Liste mit Werten und Prinzipien auf Kärtchen ist nicht genug. Gedruckt sind die nämlich geduldig. Und auch die Mahnung, man solle sich täglich um sie bemühen, ist geduldig. Im Tagesgeschäft ist das schwer. Und das nächste Refactoring ist immer weit. Und TDD ist auch nicht einfach.
Nein, ich glaube, wir müssen anders vorgehen, um schnell zu “good enough” zu kommen. Wir müssen das Schreiben der Software so verändern, dass quasi automatisch und ohne lange Diskussion “good enough” rauskommt. Alles, was nicht sofort beim Schreiben passiert, passiert nämlich tendenziell gar nicht.
Das hat TDD im Grunde schon begriffen – nur ist die Refactoring-Phase sehr unspezifisch.
Also: Wie können wir zügig begrenzte Qualität in unserer begrenzten Rationalität herstellen? Wie setzen wir uns sinnvoll Grenzen in der Entwicklung, um schlicht nicht mehr soviel falsch machen zu können?
Spendieren Sie mir doch einen Kaffee, wenn Ihnen dieser Artikel gefallen hat…
7 Kommentare:
Warum sollte ich nicht versuchen ein Optimum anzustreben und auch die Zeit dafür aufzuwenden, die ich benötige? Warum keine endlosen Diskussionen über eine einzelne Codezeile führen?
Vermutlich wird sich mein Kunde wehren und einfach nicht dafür zahlen wollen. Meiner Meinung nach werden wir von außen eh schon zu einem "good enough" gezwungen. Normalerweise ist gibt es doch einen "Kampf" zwischen den Interessen Aufwand (den jemand zahlen muss) und Qualität (die den späteren Aufwand zwar verringern mag, aber das ist dem kurzfristiger denkendem Kunden erstmal egal). Entscheidend ist aber für mich, dass diese beiden Standpunkte von zwei verschiedenen Entitäten vertreten werden.
So wie ich dich verstehe, möchtest du aber, dass sich die Entwickler selbst zu einem "good enough" durchringen. Dabei sehe ich jedoch die Gefahr, dass ohne Gegenpol, der eine hohe Qualität fordert, die Grenze für "good enough" immer weiter nach unten wandert. Auch der Kunde wird erstmal begeistert sein, dass alles so schnell geht. Wenn es dann später Wartungsprobleme gibt wird ihm aber recht egal sein, dass er dafür anfangs weniger zahlen musste.
Meine Frage ist also: Wie verhindert man, dass "good enough" qualitativ zu weit absackt?
Darum gehts ja: Einen Weg finden, echtes "good enough" zu erzeugen. Von vornherein. Da sind wir heute noch nicht.
Mit 3GL können wir schon manche Dinge nur noch "good enough" machen und schnell.
Mit GC können wir Speicher "good enough" verwalten. Kein Hahn kräht mehr nach mehr Freiheit in der Speicherverwaltung.
Mit SQL können wir auf Daten "good enough" zugreifen. Kein Hahn kräht mehr nach mehr Freiheit, wenn es um die Selektion von Daten geht.
Mit RegEx können wir in den allermeisten Fällen "good enough" pattern matching in auf Zeichenketten betreiben. Kein Hahn kräht mehr nach mehr Flexibilität - es sei denn, er kennt RegEx nicht.
Mit CoCo/R oder ANTLR können wir "good enough" Lexer und Parser definieren, um eigene textuelle Sprachen zu analysieren. Kein Hahn kräht mehr nach mehr Flexibilität.
All diese Technologie bringen "good enough" für die meisten Einsatzgebiete. Die Informatik hat sich da bewusst eingeschränkt. Es gibt nicht mehr alle Freiheitsgrade, sondern das Bewährte wurde abstrahiert. Man kann sich nun nicht mehr in Details verzetteln.
Etwas Ähnliches brauchen wir nun nicht für einen funktionalen Belang, sondern für die innere Qualität von Software. Wir dürfen uns nicht mehr so verzetteln, soviel falsch machen können bei der Strukturierung von Software.
Hochsprachen im Vergleich zu Assembler sind da ein erster Schritt gewesen. Anders als Prinzipien setzen die quasi physische Grenzen. Wenn es kein Goto mehr gibt, dann gibt es eben keins.
Diese Entwicklung muss nun weitergehen. Wo ist heute das Problem bei mangelnder innerer Qualität? Was führt immer wieder zu Problemen? Welche Freiheit müssen wir freiwillig begrenzen? Was müssen wir strenger reglementieren? Nicht nur durch Prinzipien auf Papier, sondern durch "Technologie gewordene Prinzipien".
Ich sehe es wie tanascius. Wenn man das magische Dreieck betrachtet kann man sogar drei Richtungen feststellen:
Zeit, Kosten und Qualität. Wenn an allen drei Enden von Management, Kunde und Entwickler gezogen wird sollte sich das Optimimum doch alleine bilden. Gibt man als Entwickler zu sehr nach wird schon mit einem flachen Dreieck gestartet und langfristig werden wir nur Qualität verlieren.
Ich sehe keinen Sinn darin sich zu sehr in die Management Richtung zu begeben sondern würde auf die Entwickler-Werte setzen. Als Freelancer muss ich natürlich auch die Kosten und Zeit im Blick haben, allerdings unter verschiedenen Rollen.
Good enough ist für mich eine Einsicht, kein Ziel.
Das Ziel sollte immer sein Software mit hoher Qualität zu produzieren. Good enough ist ein Check zur Prüfung der Zielerreichung.
Wie halte ich meine Software-Qualität hoch? Meine Instrumente sind Coding Dojos, Clean Code, TDD und deren Verwandtschaft. Und ich brauche exzellente, lernwillige, teamfähige Entwickler, die ein Interesse daran haben sich diese Instrumente anzueignen, sie immer wieder zu üben, sich zu verbessern und zu verschnellern. Und ich brauche Rahmenbedingungen z.B. Retrospektiven oder Vertrauen in meine Entwickler (als technische Experten).
Die Frage ist nun, wer trifft die Entscheidung auf die Frage: Gut genug? Eben jener o.g. Entwickler oder er mit seiner Organisation; und das anhand von selbst gewählten Checks (80% Code-Abdeckung steht im Level of Done, ok 82% müssen reichen!)
Ja, bitte good enough. Nein, das entscheidet nicht der Projektleiter sondern mein Gewissen.
@pvblis: Das ist ja mein Punkt: Dem Gewissen können wir das nicht überlassen. Das ist entweder nicht ausgebildet oder es hat keine Gelegenheit, seine Ausbildung anzuwenden, oder es schießt übers Ziel hinaus oder es ist schlicht nicht wirklich erkennbar, was "die beste Qualität" ist.
Schau dir das nächstbeste Drama auf der Bühne an. Am besten ein altgriechisches. Oder auch einen der aktuellere Woody Allens. Da wirst du sehen: Das Gewissen hilft nicht. Menschen verstricken sich in Probleme trotz Gewissen, weil sie kein "jetzt ist genug" Kriterium haben.
Oder schau ins Gesundheitswesen. Von dem können wir Wichtiges lernen. Zum einen, wie wichtig rigorose Praktiken sind wie Händewaschen. Zum anderen aber auch, dass Prävention (oder Qualität) "unersättlich" sein können.
Auch darf man mich nicht missverstehen, dass ich etwas Einfaches fordern würde. "Good enough" ist schwierig, weil es erstens klare Kriterien braucht und zweitens Mut, sich an sie zu halten.
Ein schöner Beitrag!
Mit "good enough" wurde ich eigentlich schon konfrontiert, seit ich Softwareentwickler bin.
"good enough" ergibt sich bei mir immer aus der Frage: "Wann soll's denn fertig sein?" und "Was soll die Software am Ende können?"
Dann wird losgelegt und am Ende steht das. Natürlich müssen nebenbei noch Bugs behoben und/oder zusätzliche Features implementiert werden. Aber "good enough" war am Ende tatsächlich immer gut genug.
Aber man wäre kein Entwickler, wenn man nicht nach Perfektion streben würde. So informierte ich mich auch mal über diverse Developer-Praktiken. TDD und sowas alles.
Mir kam es aber immer so vor, als ob jene Autoren noch nie "good enough"-Software entwickeln mussten. Es las sich alles so, wie in einem Märchenbuch. Da wurde die Code-Basis bis ins kleinste Detail verbessert, und wieder verbessert, und wieder ... am Ende war es nur noch Geschmackssache, ob des schönen Codes Willen. Und natürlich mit 100% Test-Abdeckung.
Wenn das tatsächlich die Realität wäre, müsste es überall nur noch fehlerfreie Software geben. (Vorausgesetzt, man hat alle Zeit der Welt und es kommen keine Features mehr dazu.)
Daher hielt ich meist derartige Autoren eher für realitätsfern, die in ihrer perfekten Welt leben.
Softwareentwickler, die jedoch betonten und drauf hinwiesen, dass es kein perfektes Design gibt, waren für mich glaubwürdig. Da wusste ich: "Die wissen was es heißt, Software, die good enough ist, zu erstellen."
mfg
Christian
Wenn wir uns ansehen was der Resharper in der Auto Code Generation für eine Klasse für uns erledigt:
- ToString
- Equals
- Hash
- Equals Operatoren
...
Jemand der keinen Resharper hat, hat durch C# die Möglichkeit bei der Implementierung obiger Operationen beliebig viel falsch zu machen. Das als einfaches Beispiel:
Ich stimme Ralf zu: Die nächste Generation an Programmiersprachen muss wieder einen "Fehler-mach-Möglichkeit" Freiheitsgrad mehr wegnehmen.
Kommentar veröffentlichen