Die üblicherweise ausgesprochenen Anforderungen des Kunden an eine Software sind:
- Funktionalität, z.B. die Software rechnet
- Effizienz, z.B. die Software rechnet schnell
Und zwar in der Reihenfolge, d.h. zuerst muss die Software grundsätzlich die gewünschte Funktionalität haben, dann kann ggf. an ihrer Effizienz geschraubt werden.
Schon diese beiden Anforderungen jedoch können nicht immer vollständig erfüllt werden. Es gibt Situationen, in denen muss eine Balance her. Da kann entweder nicht die volle Funktionalität geliefert werden, wenn die Effizienz für den Rest hoch genug sein soll. Oder es kann nicht die gewünschte Effizienz hergestellt werden, wenn auch die komplette Funktionalität vorhanden sein soll. Noch deutlicher wird das, wenn Effizienz aufgefächert wird in einzelne Aspekte wie Performance, Skalierbarkeit, Sicherheit, Portabilität, Robustheit, Benutzerfreundlichkeit usw.
Der trade-off lauert überall. Da ist dann die Architekturrolle gefragt, wenn z.B. zwischen Performance und Sicherheit abgewogen werden muss, oder es ist ein Gespräch angezeigt zwischen Architekt und Kunde, wenn Portabilität und Funktionalität ausbalanciert werden müssen.
Wait, there is more
Als wäre die Situation nicht schon kompliziert genug, sind das jedoch nicht alle Anforderungen. Es sind, wie gesagt, nur die irgendwie ausgesprochenen. Zu ihnen finden sich in einem Pflichtenheft oder Konzept mehr oder weniger klare Wünsche des Kunden. Dazu hat er eine Meinung und kann auch prüfen, ob eine Softwareversion ihm taugt.
Funktionalität und Effizienz bilden zusammen die Laufzeit- oder Verhaltensanforderungen.
Ohne, dass es dem Kunden (oder oft auch Management, gar Entwicklern) bewusst wäre, gibt es darüber hinaus allerdings weitere Anforderungen. Die beziehen sich auf die Lebenszeit der Software. Der Kunde kann nicht durch „Herumspielen“ mit einer Softwareversion feststellen ob und inwiefern sie erfüllt sind:
- Wandelbarkeit: Kann die Software leicht an neue Anforderungen angepasst werden?
- Regressionsfreiheit: Sind vor einer Veränderung existierende Funktionalität und Effizienz nach der Veränderung immer noch vorhanden? (Regressionsfreiheit ist Teil der größeren Anforderungskategorie Korrektheit.)
Die Anforderungen stehen auf dem Kopf
Die Liste der Anforderungen, die während der Softwareentwicklung immer wieder ausbalanciert werden müssen, ist also länger als gemeinhin angenommen:
- Funktionalität
- Effizienz
- Regressionsfreiheit
- Wandelbarkeit
Eigentlich sind alle diese Anforderungen wichtig. Der Kunde ist an der Erfüllung aller interessiert. Dennoch gibt es eine de facto Priorität. Wenn im Zweifel, dann wird eher eine höher liegende Anforderung erfüllt.
In der Praxis bedeutet das, dass Maßnahmen, die der Erfüllung einer weiter unten liegende Anforderung gelten, gestrichen werden, wenn eine darüber liegende Anforderung noch nicht ausreichend erfüllt zu sein scheint.
Die Entstehung von legacy code, die Anhäufung eines big ball of mud ist daher kein Wunder, oder? Denn die Wandelbarkeit steht ganz am Ende der Liste und gehört zu den Anforderungen, deren Erfüllung der Kunde nicht einfach überprüfen kann. So viele Anforderungen können bedürftig sein, da bleiben kaum Ressourcen, um auch noch der Wandelbarkeit zu dienen.
Solange eine Software überschaubar und keine lange Lebensdauer zu erwarten ist, mag das nicht weiter tragisch sein. Aber wer weiß denn wirklich, ob die klein geplante Codebasis wirklich klein bleibt? Ist eine Software erstmal erfolgreich, wollen Kunden mehr. Dann ist die Lebenszeit nicht absehbar. Das bedeutet, die Software muss regressionsfrei sein und bleiben und auch wandelbar sein und bleiben. Sonst besteht schlicht keine Zukunftsfähigkeit.
Schluss mit dem Kopfstand!
Zukunftsfähige Softwareentwicklung muss die Priorität der Anforderungen umkehren. Die Anforderungen müssen auf die Füße gestellt werden. Welche Funktionalität und Effizienz morgen oder übermorgen von einer Software gewünscht werden, ist unsicher. Dass jedoch anderes und mehr gewünscht wird, ist sicher.
Die erste zu erfüllende Anforderung ist mithin die Wandelbarkeit, nicht die Funktionalität!
- Wandelbarkeit
- Regressionsfreiheit
- Funktionalität
- Effizienz
Auch hier gilt wieder: Wenn im Zweifel, dann lieber eine höher liegende Anforderung erfüllen.
Oder: Wenn auf einer unteren Ebene zwei Optionen keinen Unterschied machen, dann die wählen, die auf höherer Ebene mehr Qualität bietet.
Aber wie kann Wandelbarkeit über Funktionalität stehen? Ohne Funktionalität gibt es keinen Code, der wandelbar sein könnte.
Es geht bei der Positionierung in der Reihenfolge nicht sofort und immer um Code, sondern zunächst um eine Grundhaltung. So wie bei der Fliegerei safety first gilt, sollte bei der Softwareentwicklung evolvability first gelten.
Lesen Sie die Liste gern auch im Stile des agilen Manifests: Wandelbarkeit vor Regressionsfreiheit usw.
Wandelbarkeit an erster Stelle bedeutet, nach Prinzipien zu codieren, die es erleichtern, in der Zukunft Veränderungen an Funktionalität und Effizienz vorzunehmen, sei das für Erweiterungen oder Bug Fixes.
Regressionsfreiheit an zweiter Stelle bedeutet, so zu codieren, dass automatisierte Tests erstens leicht möglich sind und zweitens auch mit einer guten Abdeckung existieren, um Regressionen zügig und mit hoher Wahrscheinlichkeit (und vor Auslieferung) festzustellen.
Und schließlich bedeuten Funktionalität an dritter und Effizienz an vierter Stelle, dass deren Realisierung nur in dem Rahmen stattfinden soll, der von Wandelbarkeit und Regressionsfreiheit aufgespannt wird. Es besteht quasi eine freiwillige Selbstbeschränkung: Funktionalität und Effizienz werden nicht mehr „irgendwie“ oder „auf Teufel komm’ raus“ hergestellt, sondern stets mit Rücksicht auf Wandelbarkeit und Regressionsfreiheit.
Wer an Funktionalität und Effizienz arbeitet, muss sich die Frage gefallen lassen, ob er die darüber liegenden Anforderungen im Blick hat.
Das bedeutet nicht, Wandelbarkeit oder Regressionsfreiheit über alles andere zu stellen. Sie sind nicht wichtiger als Funktionalität oder Effizienz. Aber sie sind eben auch nicht unwichtiger. Damit diese gleiche Gewichtung jedoch ihren Niederschlag im Code findet, ist eine neue Priorisierung nötig.
Clean Code Development wie wir es unterrichten, versteht sich mithin als Anwalt der oft unsichtbaren oder impliziten Anforderungen Wandelbarkeit und Regressionsfreiheit. Wir wollen ihnen zu ihrem gebührenden Gewicht verhelfen. Wir wollen die Anforderungsliste vom Kopf auf die Füße stellen.
Unser Ziel ist es, Softwareentwicklern und Managern (und gern auch Kunden) das Bewusstsein zu vermitteln, dass sich Zukunftsfähigkeit nicht von allein ergibt, sondern ausdrücklicher und systematischer Anstrengung bedarf.
Auf die Füße gestellte Anforderungsprioritäten sind dafür ein Bild. Daran kann sich die Diskussion entzünden. Das kann mit der Realität in einem Projekt verglichen werden. Inwieweit Softwareentwicklung sich um Clean Code bemüht, kann abgelesen werden an der Position von Wandelbarkeit und Regressionssicherheit in der Liste der Anforderungen.
Auf welchem Platz stehen diese Anforderungen denn bei Ihnen? Woran machen Sie das fest?