“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”
C. A. R. Hoare
Wenn wir Software erstellen, eine neue Methode, einen neuen Controller, ein neues Module oder ein neues Projekt , dann existiert der innere Drang, es möglichst vollständig durchzuführen.
In den meisten Fällen ist dieser Ansatz falsch. Die Anforderungen für ein Entwickler Team muss man sich als einen Baum vorstellen, bei dem zu Beginn nur der Stamm zu sehen ist. Der Rest des Baumes ist in Nebel gehüllt. Das dort oben eine Baumkrone vorhanden sein muss, ist dem Entwickler klar, und einige Äste sind im Nebel verschwommen zu erkennen.
Nun gibt es zwei Möglichkeiten mit diesem Stand der Anforderungen umzugehen. Die erste einfache und recht naive Möglichkeit ist es, alles was man vermeintlich sieht umzusetzen. Diverse Projekte, Packages, Klassen und Methode als leere Hüllen erzeugen und sie später bei Bedarf füllen.
Die andere Möglichkeit ist es, einen speziellen Ast genauer ins Auge zu fassen und auf den Baum zu klettern. Dann schaut man die Äste soweit hinauf, wie es möglich ist und implementiert eine Lösung für das, was man an Anforderungen vor Augen hat.
Warum ist die erste Möglichkeit naiv und warum wird bei der zweiten Möglichkeit nicht die gesamte Baumkrone erkundet um dann alles umzusetzen? Beides hat mit einer Eigenschaft von Software Projekten zu tun, die auch in der Analogie zum Baum zu finden ist. Bäume wachsen und verändern sich. Manche Äste sterben ab und fallen vom Baum und manche junge Triebe entwickeln sich neu. Während wir also die Anforderungen sammeln und daraus eine Lösung entwickeln, verändern sich die Anforderungen.
Diese Veränderungen der Anforderungen ist die Antriebskraft agiler Vorgehensweisen. Längerfristige Analyse- und Designphasen bedeuten Verschwendung, wenn die daraus resultierenden Pläne später zwangsläufig über den Haufen geworfen werden müssen. Auch das Implementieren von Funktionalitäten oder die Bereitstellung von Resourcen, die später benötigt werden ist Verschwendung. Auch hier ist es nicht sicher, dass diese Dinge tatsächlich verwendet werden. Fällt eine entsprechende Anforderung im Projektverlauf fort, dann ist die geleistete Arbeit unnötig gewesen und der Ausbau der vermeintlich notwendigen Funktionalität kostet weiteres Geld.
Viele Wasserfall Projekte leiden an dem Umstand, dass bei der Implementierung nicht darauf geachtet wird, dass jederzeit funktionierende Zwischenstände bereitgestellt werden können. Im Beitrag Von Brücken und Tunneln wurde dieses Phänomen mit einem Tunnelbau verglichen. Da ein kompletter Plan der Umsetzung steht, kann mit einzelnen unzusammenhängenden Abschnitten begonnen werden. Wie eine Tunnelbaustelle kann diese Software erst kurz vor Beendigung erstmalig genutzt werden. Missverstandene, vergessene oder neue Anforderungen werden erst dann entdeckt, wenn es eigentlich schon zu spät ist.
Auch agile Projekte können durch frühe, unnötige Festlegungen in der Implementierungen gestört werden. Dinge nicht frühzeitig festzulegen, sondern erst in dem Moment in dem die Entscheidung notwendig wird, ist keine Schwäche sondern ein großer Vorteil agilen Arbeitens.
Die Vermutung, später mit 20 Services zu arbeiten, kann zwar korrekt sein, aber was passiert, wenn es dann doch 13 Services sein könnten oder 23? Manches Mal belässt es das Team dann bei den 20 schon vorbereiteten Services und verbiegt den Entwurf soweit, dass es passt. Damit hat man durch eine vermeidbare Entscheidung technische Schulden produziert, die vielleicht niemals wieder aus dem Projekte entfernt werden. Auch Jahre später wird ein älterer Kollegen dem neuen Entwicker erklären müssen, warum die Architektur des System inkonsistent ist.