Einleitung
Bevor ich dir konkrete “Tipps&Tricks” für die nachhaltige Softwareentwicklung gebe, möchte ich dir ein big picture skizzieren. Zu oft habe ich gehört und gelesen, dass einzelne Prinzipien und Praktiken empfohlen werden, ohne einen Kontext, ohne eine “Herleitung”. Bei aller Richtigkeit dieser Empfehlungen werden sie dann aber leicht missverstanden oder eben eingesetzt, wenn der Kontext nicht passt. Das führt zu Frustration. Die möchte ich dir ersparen, so weit es mir möglich ist.
Es ist schwer genug, all das in Worte, auch noch lineare zu fassen, was ich dir vermitteln will für nachhaltige Softwareentwicklung. Es wird mir auch nur bruckstückhaft gelingen. Dass du mich missverstehst, ist für mich vorhersehbar und unvermeidbar. Doch ich will mich bemühen, das zu minimieren. Und eine auf der Hand liegende Maßnahme dafür ist, dass ich etwas aushole, um einen Rahmen aufzuspannen, in dem das konkrete Thema dieses Buches und der anderen der Reihe eingehängt werden kann.
Deshalb: Halte einen Moment durch, bis es an das eigentlichen Thema dieses Bandes. Keine Sorge, du wirst davon genug zu sehen bekommen.
Und nun gehts los. Wo sonst als am Anfang jedes Softwareprojektes, bei den Anforderungen:
Anforderungskategorien
Softwareentwicklung hat Anforderungen in drei Kategorien zu erfüllen, um ihr Geld wert zu sein:
- Zunächst muss Softwareentwicklung funktionierende Software liefern. Auftraggeber haben funktionale Anforderungen an Software, die sie erfüllt sehen wollen. Nur dann hat die Funktionalität von Software hohe Qualität. Das ist so natürlich, dass es kaum der Rede wert ist - dennoch müssen wir da noch genauer hinschauen, auch wenn ich denke, mit diesen Anforderungen bist du bestens vertraut. Sie treiben dir genug Schweiß auf die Stirn.
- Funktionalität allein ist allerdings nicht genug - auch das ist dir klar - und noch nicht einmal der Grund für die Beauftragung von Softwareentwicklung. Software soll vor allem nicht-funktionale Anforderungen erfüllen! Sie soll Funktionalität besser (Komparativ!) anbieten als die Alternative (z.B. bisherige Software oder Handarbeit). Software soll z.B. schneller oder einfacher oder skalierbarer oder sicherer funktionieren als die Alternative. Dann hat die Effizienz1 von Software hohe Qualität. Das ist ebenso natürlich, dass es kaum der Rede wert ist - aber diese Anforderungen bereiten dir womöglich noch mehr Kopfschmerzen als die funktionalen.
Funktionale und nicht-funktionale Anforderungen zusammen sind Verhaltensanforderungen an Software. Der Auftraggeber kann durch Ausführung der Software überprüfen, ob die geforderte Qualität hergestellt wurde. Dieser Oberbegriff ist wichtig, wie du im Weiteren sehen wirst.
Vielleicht überraschend für dich, sehe ich Korrektheit darin noch nicht subsummiert. Korrektheit ist keine explizite weitere Anforderung an Software, sondern ist impliziet in der Erwartung, dass spezifizierte Anforderungen tatsächlich durch gelieferte Software erfüllt werden. Software ist also in dem Maße korrekt, in dem sie die Spezifikation erfüllt.
Mach dir an dieser Stelle keinen Kopf über den Begriff Spezifikation. Ich will damit keine Norm heraufbeschwören, sondern verstehe darunter lediglich eine irgendwie gearbeitet Liste von gewünschten Eigenschaften. Ob die auf einer Serviette stehen oder in einem 500seitigen Buch gebunden sind, ist einerlei. Der Kunde kann zur Laufzeit diese Liste abhaken und den Erfüllungsgrad seiner Wünsche messen. Korrektheit liegt vor, wenn der Erfüllungsgrad 100% ist. Fehlt allerdings ein Wunsch in der Spezifikation und ist deshalb nicht implementiert, ist das Verhalten der Software nicht inkorrekt, selbst wenn der Kunde bei der Überprüfung das Verhalten vermisst.
It’s the productivity, stupid!
Über die Verhaltensanforderungen hinaus hat der Auftraggeber noch eine weitere Anforderung, die jedoch selten ausdrücklich formuliert oder gar vertraglich festgehalten wird. Das ist nun ein ganz wesentlicher Punkt; pass auf, denn es geht um dich und dein Team! Hier kommt die Motivation für Agilität und Clean Code Development:
- Die Softwareentwicklung soll stets zügig funktionale wie nicht-funktionale Anforderungen erfüllen. Auftraggeber haben also auch noch einen Anspruch an die Produktivität der Softwareentwicklung.
Verhaltensanforderungen werden unmittelbar durch Code erfüllt. Die Produktivitätsanforderung hingegen ist eine an die herstellende Organisation.
Wie Funktionalität mittels Code hergestellt wird, ist eine Sache von Programmiersprachen, Bibliotheken und Frameworks. Diese Fähigkeit ist die primäre, die du als Softwareentwickelnde(r) erwirbst und stetig verfeinerst.
Wie Effizienzen mittels Code hergestellt werden, ist ebenfalls zunächst eine Sache von Programmiersprachen, Bibliotheken und Frameworks. Diese Fähigkeit wird gewöhnlich später erworben, ist letztlich jedoch die, auf die sich viele Entwickelnde konzentrieren. Bücher wie “Algorithmen und Datenstrukturen” beschäftigen sich mit diesem Thema.
Nicht immer jedoch lässt sich damit das geforderte Qualitätsniveau schon erreichen. Performance oder Skalierbarkeit brauchen oft Unterstützung durch Verteilung von Code zur Laufzeit auf verschiedene Threads im selben Betriebssystemprozess oder in verschiedenen oder gar auf mehreren Rechnern oder in unterschiedlichen Netzwerken. Damit beschäftigt sich traditionell die Softwarearchitektur. Hier warten große Herausforderungen! Hier kannst du der Held so mancher Infrastrukturtechnologie werden.
Doch selbst wenn du gut dabei bist in der Herstellung von Funktionalität und Effizienz, kann es leicht sein, dass der Auftraggeber nicht mit dir zufrieden ist. Wie kann das sein? Du bist vielleicht einfach zu langsam. Perfekte Verhaltensqualitäten lieferst du, nur leider zu spät. Potenziert wird das, wenn du auch noch unzuverlässig bist, d.h. die Lieferung bis zu einer Frist versprichst und dann doch nicht lieferst.
Für den Auftraggeber gibt es also zwei “Laufzeiten”: die Software-Laufzeit und die Team-Laufzeit. An beide hat er Anforderungen. Die Software soll performen, das Team aber auch. Letzteres setzt der Auftraggeber allerdings mehr oder weniger voraus. Dafür schreibt er keine Spezifikation. Er glaubt einfach, dass du professionell arbeitest. Dazu gehört für ihn, dass du stets “flott dabei bist” und dir kein Bein stellst. Leider ist das oft nicht der Fall. Softwareentwicklung fällt immer wieder über die eigenen Füße; sie merkt sozusagen nicht, dass sie mit zusammengebundenen Schnürsenkeln läuft.
Aber wie kann das sein? Ich denke, dafür gibt es viele Gründe. Neben historischen, sozusagen systemimmanenten gibt es jedoch einen immer wieder ganz akuten: Druck. Die Softwareentwicklung wird vom Auftraggeber oft sehr mit Deadlines unter Druck gesetzt (und lässt sich auch unter Druck setzen), so dass sie meint, nie Zeit zu haben, die Schnürsenkel ordentlich zu binden. Lieber stolpert sie dahin, stets willig, dem Kunden Verhaltensanforderungen grob zu erfüllen, als dass sie sich “sauber aufstellt” und “fit hält”.
Produktivitätskiller
Der Auftraggeber der Softwareentwicklung schaut gewöhnlich vor allem auf die Erfüllung von Verhaltensanforderungen. Das ist für ihn am einfachsten. Das merkst du jedes Mal, wenn Abnahme ist. Darum drehen sich dann die Diskussionen. Über den Herstellungsprozess, wie es zum präsentierten Verhalten gekommen ist, wird nicht diskutiert. Jedenfalls nicht direkt. Dafür fehlt ja eine Spezifikation. Was aber eben nicht heißt, dass der Kunde zur Team-Performance keine Meinung hätte.
Hohe Produktivität von dir und deinem Team wird einfach vorausgesetzt. Wie die Erfahrung jedoch zeigt, ist es eine naive Erwartung, dass hohe Produktivität nach einem vielleicht anfänglich guten Start “einfach so” erhalten bliebe. Die Produktivitätskurve sink vielmehr relativ schnell auf einen bedauerlich niedrigen Wert. Hier eine typische Darstellung der Entwicklung (Quelle):
Produktiv sind Entwickelnde nicht einfach, weil sie gerade codieren. Nur weil du dich gestresst fühlst beim Programmieren, performst du nicht automatisch im Sinne des Auftraggebers. Das mag enttäuschend klingen, ist aber die Realität. Solange es da ein Missverständnis zwischen dir und dem Auftraggeber gibt, sind Konflikte unvermeidlich.
Nicht jede geschriebene/veränderte Codezeile trägt zur Produktivität bei, wie der Auftraggeber sie sich wünscht. Produktiv ist die Softwareentwicklung nur, wenn sie neue Anforderungen erfüllt, d.h. an Features arbeitet. Das kann durch Codierung geschehen oder durch andere, vorgelagerte Tätigkeiten.
Je öfter du Features lieferst, d.h. Erweiterungen, Verbesserungen - keine Bug Fixes (!) - und die auch noch korrekt lieferst, desto produktiver bist du aus Sicht des Auftraggebers.
Wenn du also auch die (unausgesprochenen) Anforderungen des Auftraggebers an deine Produktivität erfüllen willst, tust du gut daran, alles was dabei hinderlich sein könnte, zu vermeiden. Wenn du während des Kochens eines Abendessens merkst, dass dir eine Zutat fehlt und du losrennst, um sie zu kaufen, bricht deine Produktivität ja auch ein. Dito, wenn du mit dem Kochen beginnen willst und findest die Spüle voll mit dreckigen Töpfen. Dito, wenn du dich zum Date fertigmachen willst und feststellen musst, dass deine beste Hose noch in der Wäsche ist. Wann immer also etwas fehlt, das du brauchst, um zu tun, was du eigentlich tun willst, stehst du einem Produktivitätskiller gegenüber.
Vorausgesetzt, dass du technisch und fachlich kompetent bist - auch daran hat ein Auftraggeber Interesse -, sehe ich vor allem drei Produktivitätskiller, die du ausschalten musst:
Fehlende Korrekheit
Die Softwareentwicklung kann sehr geschäftig codieren, ohne produktiv zu sein. Das ist immer der Fall, wenn sie Bug Fixing betreibt.
Bugs zu fixen ist Nacharbeit (re-work). Nacharbeit oder Ausbesserung von Defekten ist eine der Verschwendungsarten in der Lean “Philosophie”. Aus Sicht des Kunden vertust du deine Zeit mit Dingen, die schon lange hätten erledigt sein sollen. Statt Bugs zu fixen, wäre es dem Auftraggeber lieber, dass du schon wieder an neuem Verhalten arbeitest.
Jede Stunde, die du mit Bug Fixing verbringst, fehlt dir für die Feature-Produktion. Das Bug Fixing zu begrenzen, selbst wenn noch Bugs bekannt sind, ist daher eine notwendige Maßnahme, um produktiv zu bleiben2. Besser jedoch, wenn die Softwareentwicklung gar nicht erst in diese Verlegenheit kommt. Warum nicht Bugs von vornherein einfach vermeiden?
Um die Produktivitätsanforderung des Kunden zu erfüllen, muss Korrektheit die oberste Priorität haben.[^klarheitsprämisse]
[^klarheitsprämisse]: Prämisse hierbei ist, dass klar ist, welches Verhalten die Software überhaupt haben soll. Korrektheit meine ich nur auf das, was klar spezifiziert ist. Wo Klarheit fehlt - allemal unwissentlich -, sind überraschende Qualitätsmängel unvermeidbar. Das sind dann jedoch keine Inkorrektheiten.
Korrektheit ergibt sich allerdings nicht einfach, sondern muss systematisch hergestellt und erhalten werden.
- Zunächst ist bei der Feature-Produktion (und auch beim Bug Fixing) Korrektheit in Form von Reife zu erreichen. Zu jedem Zeitpunkt bzw. spätestens vor Präsentation/Auslieferung eines Softwarestandes musst du prüfen, ob deine Software schon korrekt ist gem. der Spezifikation. Haben deine Anstrengungen zur Herstellung gewünschter Qualitäten schon ausreichenden Erfolg gehabt? Wenn du keine Differenz mehr siehst zwischen spezifiziertem und realem Verhalten, dann ist dein Code reif für die Präsentation beim Auftraggeber.
- Darüber hinaus ist allerdings stets sicherzustellen, dass bei der Feature-Produktion vorher erreichte Korrektheit nicht zerstört wird. Es darf keine Regression stattfinden, d.h. kein Rückfall auf ein früheres, niedrigeres Korrektheitsniveau. Der Auftraggeber erwartet Stabilität der Software in Bezug auf die Korrektheit. Während der Veränderung von Code bzw. spätestens vor Präsentation/Auslieferung eines Softwarestandes musst du deshalb immer wieder überprüfen, ob deine Software noch korrekt ist gem. der Spezifikation. “Verschlimmbesserung” ist eines der größten Risiken in der Softwareentwicklung.
Maßnahmen für die Korrektheit umfassen z.B. den Abnahmetest, eine Beta-Test-Phase, die Beschäftigung von Testern, die Definition eines Done-Zustands inkl. Akzeptanzkriterien, automatisierte Tests, eine Continuous Build/Integration Pipeline oder die Codierung nach Test-Driven Development (TDD).
Produktivität braucht Sorgfalt. Es sind “die Dinge richtig zu tun”. So wird landläufig auch Effizienz beschrieben. Man weiß, was zu tun ist - und tut es dann auch so, wie es getan werden sollte. Die Verhaltensanforderungen sind klar, die Softwareentwickelnden sind kompetent, das Ergebnis ist korrekte Software. So sollte es zumindest sein. Das ist die Erwartung des Auftraggebers. Doch so einfach ist es nicht…
Überlege selbst, welche der obigen (oder auch weiteren) Maßnahmen in deinem Team verlässlich getroffen werden, um hohe Korrektheit zu liefern und zu erhalten.
Fehlender Wert
Aber was, wenn die Softwareentwicklung nicht weiß, was zu tun ist? Was, wenn Unklarheit herrscht? Die Voraussetzung dafür, “die Dinge richtig zu tun” ist, dass man überhaupt “die richtigen Dinge tut”. So wird landläufig Effektivität beschrieben. Effektivität kann es nur geben, wenn Klarheit herrscht.
Solange die Softwareentwicklung aber im Unklaren darüber ist, was genau die Verhaltensanforderung ist oder solange der Auftraggeber selbst sich noch nicht ganz klar darüber ist, wie für ihn hohe Verhaltensqualität aussieht, kann Codeproduktion nicht effektiv sein. Und ohne Effektivität keine Produktivität.
Leider ist das der natürliche Zustand von Softwareprojekten:
- Der Auftraggeber hat eine nur unvollständige Vorstellung davon, was er braucht.
- Der Auftraggeber kann seine Vorstellungen nur unvollständig formulieren.
- Die Softwareentwicklung versteht die formulierten Anforderungen nur unvollständig.
- Die Softwareentwicklung setzt ihr Verständnis der Anforderungen nur unvollständig um.
- Der Auftraggeber hat in der Zeit von der Spezifikation bis zur Abnahme ihrer Umsetzung3 seine Meinung geändert; seine Anforderungen sehen nun anders aus. Selbst eine korrekte Umsetzung der ursprünglichen Spezifikation passt daher nur unvollständig zum neuen Stand der Bedürfnisse des Auftraggebers.
Das ist die Erkenntnis der Agilität in der 1990ern gewesen, die zur Mindestforderung eines iterativ-inkrementellen Softwareentwicklungsprozesses geführt hat.
Als Produktivitätskiller hatte sich herausgestellt, dass immer wieder überraschend bei der Abnahme von Software nicht der erwartete Wert geliefert wurde. Selbst spezifikationsgemäße Lieferung hatte nicht die im praktischen Einsatz erforderlichen Nutzen.4
Das Missverständnis von Auftraggebern und Softwareentwicklung bis in die 1990er war (und ist leider auch heute noch in einigen Projekten), dass Verhaltensanforderungen sich in einem mehr oder weniger länglichen Prozess einmalig vor Beginn der Umsetzung festzurren lassen könnten (Stichwort “Wasserfall”).
Diese Vorstellung hat zu Spezifikationen geführt, die große, unvermutete Missweisungen enthielten, die in Software gegossen große negative Überraschungen ausgelöst haben. Umfangreiche Nacharbeiten waren nötig, nicht wegen Inkorrektheit, sondern wegen Wertlosigkeit. Auch korrekt implementierte Spezifikationen haben zum Lieferzeitpunkt nichts oder zu wenig genützt.
Dem hat die Agilität eine Desillusionierung entgegen gesetzt. Nicht noch bessere, umfangreichere, längere Anforderungsanalyse soll die Produktivität steigern, sondern das Gegenteil: eine radikale Verkürzung bei gleichzeitiger Vervielfachung von Analyse, Spezifikation und Umsetzung.
In der Agilität gibt es weiterhin eine Spezifikation und insofern eine Erwartung an hohe Korrektheit (Stichwort “Definition of Done”). Doch es wird nicht mehr angenommen, dass diese Spezifikation schon “die letzte Wahrheit” sei. Stattdessen soll die Softwareentwicklung bestrebt sein, nur schmale Ausschnitte eines Gesamtverhaltens zu spezifizieren (auch Inkremente genannt), die zügig umgesetzt werden können, um vom Auftraggeber Feedback zu bekommen. Wert kann man sich nur schrittweise annähern, nicht, weil Auftraggeber oder Softwareentwicklung inkompetent sind, sondern weil es in der Natur der Sache komplexer Anforderungen liegt; da ist kein geradliniger Weg zu hohem Wert sichtbar.
Man bekämpft beim iterativ-inkrementellen Vorgehen die Ineffektivität dadurch, dass man ihr den Zahn der Überraschung zieht. Denn nur die Überraschung macht aus mangelndem Wert frustrierende Nacharbeit. Ist mangelnder Wert jedoch zu erwarten, ja, geradezu die Norm, dann ist die nächste Iteration keine Nacharbeit, keine Verschwendung, sondern ein erwartetes Inkrement und insofern produktiv - auch wenn man gern schneller vorangehen würde.
Softwareentwicklung wie Auftraggeber hegen beim agilem Vorgehen nicht mehr den Glauben, dass wertvolle Software “in einem Rutsch” entstehen kann. Vielmehr muss man sich hohem Wert experimentierend mit hochqualitativen Inkrementen annähern. Das ist keine Last, das ist eine Tugend, weil unvermeidbar.
Wie steht es mit diesem Verständnis in deinem Team? Geht ihr iterativ-inkrementell vor? Versteht der Auftraggeber die Vorläufigkeit seiner Anforderungen und eurer Lösungen?
Fehlende Ordnung
Auch wenn fehlende Korrektheit der naheliegende und greifbare Produktivitätskiller ist, ging ihm geschichtlich fehlender Wert in der Bewusstwerdung der Softwareentwicklung voraus, denke ich.
Nicht genau zu wissen, was der Auftraggeber wirklich will, was für ihn Wert darstellt, für das Geld, das er auszugeben bereit ist, war zunächst ein größeres Problem. Erst als eine Verbesserung des Vorgehensmodells in den 1990ern hier mehr Klarheit gebracht hatte und dadurch die Zahl der Softwarelieferungen zur Feedback-Generierung, die potenziell inkorrekt sein konnten, gestiegen war, trat der Produktivitätskiller Inkorrektheit deutlich(er) zutage. Beleg ist aus meiner Sicht dafür die späte Erfindung automatisierter Tests. Erst Ende der 1990er bekam das Thema breite Sichtbarkeit.
Wenn man weiß, was das Richtige ist (Wert), lohnt es, das auch richtig zu tun (Korrektheit). Wenn man es kann.
Und da steckt schließlich der dritte Produktivitätskiller, den ich dir vorstellen möchte: die Unordnung. Solange du nicht bewusst darauf achtest, Ordnung im Code herzustellen, hast du es immer schwer, das Richtige auch richtig zu tun.
Code, der sich mit jedem neuen Feature, mit jedem Bug Fix weniger leicht verändern lässt, wird zum Morast, in dem deine Softwareentwicklung alsbald steckenbleibt. Oder wenn nicht steckenbleibt, dann zumindest nur noch schwerfällig vorankommt. Das ist nicht, was Auftraggeber sich wünschen.
Code ist eine Ressource, mit und an der Softwareentwicklung arbeitet. Wie andere Ressourcen kann sie pfleglich behandelt werden - oder man treibt an ihr Raubbau. Ohne weitere Maßnahmen geschieht Letzteres.
Für den Auftraggeber sind Inkorrektheit und Wertarmut von Code noch vergleichsweise leicht zu spüren. Beide zeigen sich als mangelnde Qualitäten im Verhalten.
Unordnung jedoch entzieht sich der direkten und zeitnahen Wahrnehmung des Auftraggebers. Deshalb hat sie Gelegenheit, sich hinter der Fassade des Verhaltens aufzubauen. Wenn sie dann indirekt über deutlich sinkende Produktivität auch für den Auftraggeber spürbar wird, ist es jedoch eigentlich schon zu spät. Deshalb musst du ständig ein Auge auf die Ordnung haben!
Wenn du die Ordnung zu lange hast schleifen lassen, sind die nötigen “Aufräumarbeiten” meist zu umfangreich, als dass sie sich rechnen würden. Und sie ließen sich auch kaum dem Kunden gegenüber verheimlichen. Also schleppt sich die Softwareentwicklung weiter durch den selbst verschuldeten Sumpf. Denn selbst verschuldet ist er, da der Kunde sich Unordnung nicht gewünscht hat. Sie ist mangels Bewusstsein und/oder mangels Fähigkeit und/oder wider besseren Wissens “auf Befehl” (Ignoranz) und/oder in naivem Glauben an baldige Korrektur (so genannte Technische Schuld) entstanden.
Nicht, dass fehlende Ordnung eine neue Ursache für Produktivitäsabnahme wäre. Sie wurde schon in den 1960ern oder gar früher identifiziert. Auch die Strukturierte Programmierung (structured programming) ist aus dieser Erkenntnis entstanden. Man könnte wohl auch sagen, dass Objektorientierung von ihr ursprünglich inspiriert war. Ebenso das structured design und der Begriff des Moduls.
Wer mit Code zu tun hat, erwartet, ordentlichen Code vorzufinden, d.h. Code, der nicht unnötig behindert, ihn zu verstehen (“easy to reason about”), und der nicht unnötig behindert, ihn zu verändern. Denn darum geht es letztlich ja immer: Code wird nur betrachtet, um ihn neuen Anforderungen anzupassen oder zu korrigieren. Dass du Code aus Spaß am prasselnden Kaminfeuer studierst, passiert wahrscheinlich selten, oder?
Nach Jahrzehnten des mehr oder weniger latenten Bewusstseins der Branche, dass Ordnung eine Qualität ist, auf die es ebenfalls zu achten gilt bei der Softwareentwicklung, hat dann im Jahr 2008 der Begriff Clean Code dem Thema neue Sichtbarkeit und Konkretheit gegeben.
Dass Robert C. Martin von sauberem Code und nicht von ordentlichem spricht, mag dem von Martin Fowler im Zusammenhang mit dessen Buch Refactoring geprägten Begriff code smell geschuldet sein. Was sauber ist, riecht nicht.
Doch letztlich ist Sauberkeit als Bild zu schwach für die nötige Eigenschaft, die Code haben muss, um deine Softwareentwicklung nicht schwerfällig zu machen. Was sauber ist, kann immer noch unordentlich, d.h. unüberschaubar bis zu Unbrauchbarkeit sein.
Wenn du dir jetzt allerdings Ordnung vorstellst, denkst du sehr wahrscheinlich nicht nur an Sauberkeit als Selbstzweck, sondern auch noch an Eignung für weitere Nutzung. Sauberkeit schützt vor Schaden.
Und genau darum geht es, wenn ich hier von ordentlichem Code, von Ordnung im Code spreche. Code soll ordentlich sein, um zu zügiger Veränderung zu befähigen.
Zusammenfassung
Auftraggeber wollen Software, die umfassend tut, was sie tun soll; sie soll funktional und effizient sein. Diese Qualitäten sollst du in der Softwareentwicklung stets zügig liefern; du sollst produktiv sein und bleiben.
Unglücklicherweise ist schon die Herstellung von funktionalem und effizientem Code eine Sache, die sehr komplex ist. Ich denke, davon kannst du ein Lied singen. Sich mit all den Technologien und Produkten und Ansätzen auszukennen, die zur Herstellung von funktionalem und effizientem Code zur Verfügung stehen, ist eine Kunst für sich.
Und nun soll die Herstellung von Code, der hochqualitatives Verhalten zeigt, auch noch stets zügig stattfinden, obwohl dieser Code ständigen Änderungen unterliegt und die Anforderungen an ihn notorisch unklar sind? Das steigert die Komplexität der Softwareentwicklung erheblich!
Wie es für die Herstellung von Verhaltensanforderungen Werkzeuge gibt, so gibt es zum Glück aber auch Werkzeuge, die dir helfen, hohe Produktivität zu produzieren.
- Agilität
- Automatisierte Tests
- Prinzipien und Praktiken des Clean Code Development
Du musst diese Werkzeuge kennen und auch einsetzen. Sie sind nicht neu, sie sind womöglich noch nicht einmal schwierig zu beherrschen - doch sie haben eines gemeinsam: sie gehen ans Eingemachte. Damit du sie konsequent benutzt, musst du eine passende Grundhaltung entwickeln; die Kultur der Softwareentwicklung in deinem Team und darüber hinaus muss darauf ausgerichtet sein. Das braucht Zeit.
Die Agilität hat es inszwischen geschafft, breit ins Bewusstsein (oder zumindest auf die Lippen) der Branche zu dringen. Auf die eine oder andere Weise wird also in vielen Softwareentwicklungsteams versucht, die Wertproduktion hoch zu halten durch iterativ-inkrementelles Vorgehen.
Mit der Korrektheit und der Ordnung hingegen, steht es weniger gut. Das liegt daran, dass das eine vom anderen abhängig ist: ohne Ordnung ist es schwer, Korrektheit zuverlässig und nachvollziehbar herzustellen und zu überprüfen. Aber gerade die Ordnung hat es in sich. Nicht umsonst ist sie geschichtlich der letzte Produktivitätskiller, für den breites Bewusstsein geschaffen werden musste.
So verständlich es war, dass der Fokus von der Steigerung der Produktivität in Bezug auf den Wert von Software (in den 1990er Jahren) zur Steigerung der Produktivität durch Erhöhung der Korrektheit (in den 2000er Jahren) gewandert ist - so ist es andererseits auch verständlich, dass die Produktivitätssteigerung dann gegen eine gläserne Decke stoßen musste. Erst durch einen weiteren Wechsel des Fokus hin zur Ordnung (in den 2010er Jahren) kann nämlich die Behinderung aus dem Weg geräumt werden, die mehr Korrektheit und auch zügigerer Wertherstellung im Wege stand.
Dauerhaft hohe Produktivität braucht…
- eine Organisation, die ihr höchste Priorität zuweist, um langfristig wettbewerbsfähig zu bleiben,
- ein Verständnis dafür, was Ordnung im Code bedeutet, wie er stets wandlungsfähig gehalten werden kann,
- den Willen zur Produktion von stabil korrektem Code, um die Kapazität für die Erweiterung von Code maximal zu halten,
- den Mut, nur auf der Basis von unzweideutigen Spezifikationen Code zu produzieren
- und schließlich die Einsicht, dass Unklarheit und Volatilität ständige Begleiter der Softwareentwicklung sein werden, so dass Vorläufigkeit auf allen Ebenen akzeptiert werden muss.
Leider ist es in der Softwareentwicklung so, wie es der Buddha für das Leben konstatiert hat:
“Frische Milch braucht Zeit zum Sauerwerden, / Unheilsames Handeln braucht Zeit zum Reifen, / So schwelen im Toren die Folgen seines Handelns, / Wie unter der Asche verborgene glühende Kohlen.”, Dhammapada - Die Weisheitslehren des Buddha, Munish B. Schiekel
Die negativen Auswirkungen deines heutigen Handelns zeigen sich nicht immer sofort. Sie wachsen unsichtbar und schleichend an – bis du sie irgendwann und oft zu spät deutlich spürst.
Deshalb ist es wichtig, die Produktivität als im Grunde höchstes Gut, als wichtigste Anforderung zu verstehen und die Softwareentwicklung dahingehend zu organisieren. Das ist nachhaltige Softwareentwicklung. Zuerst und unverbrüchlich soll Produktivität geliefert werden, dann erst Funktionalität, dann Effizienz.
Maßnahmen zur korrekten Wertproduktion in Ordnung müssen einen Rahmen aufspannen, in dem konkrete funktionale und nicht-funktionale Anforderungen umgesetzt werden. Derzeit geschieht es vielfach noch umgekehrt: Verhaltensanforderungen werden “irgendwie” realisiert und insbesondere Korrektheit und Ordnung sind nachrangig.
Alles, was ich dir im Folgenden präsentiere, darfst du vor diesem Hintergrund verstehen. Ich möchte dir ein methodisches Rahmenwerk vorstellen, mit dem du systematisch für höhere Korrektheit und Ordnung in deinem Code sorgen kannst. Mich treibt die eigene leidvolle Erfahrung an, dass darauf einfach zu wenig und zu spät geachtet wird. Mir ist das früher auch oft passiert - weil ich es nicht besser wusste. Dir möchte ich diese Erfahrung ersparen. Dir möchte ich eine Guideline an die Hand geben, mit der du während der Codierung deinen Weg zur Korrektheit und Ordnung findest. Keine Angst mehr vor dem blinkenden Cursor, der dich auffordert, vor allem Funktionalität zu produzieren. Mit ein bisschen System, gutem Willen und Übung wirst du es schaffen, Funktionalität und dauherhaft hohe (oder zumindest höhere) Produktivität herzustellen.