Beyond Agile

Beyond Agile: Antifragilität in der Softwareentwicklung

Gerrit Beine

© Shutterstock.com / imagevixen

In Softwareprojekten kommt es immer wieder zu Ereignissen, die nicht vorhersehbar sind. Manchmal sind deren Auswirkungen so drastisch, dass sie dem Typ Ereignis entsprechen, das seit Nassim Nicholas Taleb als Schwarzer Schwan bezeichnet wird (siehe: Taleb, Nassim N.: „Der Schwarze Schwan“). Um solche Schwarzen Schwäne als Grundlage von Verbesserung zu nutzen, muss ein System eine besondere Eigenschaft haben: Es muss antifragil sein (siehe: Taleb, Nassim N.: „Antifragilität“). Erste Ideen, wie die Bereiche Softwarearchitektur und Projektmanagement von Antifragilität profitieren können, will dieser Artikel zeigen.

In den letzten fünfzehn Jahren habe ich kein einziges Softwareprojekt erlebt, bei dem nicht irgendwann die Anforderung auftauchte. Die Anforderung führte dazu, dass alle in der Vergangenheit getroffenen Entscheidungen in Bezug auf Architektur, Datenmodell, Schnittstellen oder andere relevante Bestandteile der Software in Frage gestellt werden mussten. Manchmal konnte die Anforderung wegdiskutiert werden, manchmal wurde sie zurückgezogen. Oft genug geschah es aber, dass die Anforderung realisiert werden musste. Die Aufwände dafür waren immens, die Frage nach der Wirtschaftlichkeit wurde besser gar nicht erst gestellt.

Da es in der Softwareentwicklung wenig gibt, das wirklich unmöglich ist, wurde die Anforderung natürlich – mit kleinen Kompromissen – umgesetzt. Was im Nachhinein in diesen Projekten geschah, war immer wieder aufs Neue faszinierend. Nachdem die Anforderung realisiert war, war allen klar, wo der Fehler lag: Die Entwickler konnten schlüssig zeigen, dass es sich um einen Spezifikationsfehler der Analysten handelte, die Analysten bewiesen, dass die Architekten nicht vorausschauend genug arbeiteten, die Architekten erklärten, die Projektleitung habe falsch geplant.

Interessanterweise kam niemand auf die Idee, einen solchen Fall als normal zu betrachten. Ich auch nicht, bis ich begann, mich mit Denkmodellen und unwahrscheinlichen Ereignissen zu beschäftigen. Mir wurde klar: In der Retrospektive konnten alle genau erklären, warum die Anforderung für das Projekt so kritisch wurde. Nur vorhersehen konnte es niemand. Weil die Anforderung ein Schwarzer Schwan ist.

Der Schwarze Schwan und die Five Orders of Ignorance

Die Bezeichnung Schwarzer Schwan geht auf einen systematischen Denkfehler zurück, der uns Menschen zu eigen ist: Wir gehen häufig davon aus, dass empirische Erfahrungen mit unbedingten Wahrheiten übereinstimmen. Dabei reicht schon eine einzige Abweichung, um dieses empirische Wissen zu falsifizieren. Im Falle der Annahme, alle Schwäne seien weiß, fand dieses Ereignis durch die Entdeckung von Australien statt, denn dort gibt es schwarze Schwäne.

Unsere menschliche Neigung, das eigene, empirisch gesammelte Wissen sehr hoch zu bewerten, führt immer wieder dazu, dass wir von unvorhersehbaren Ereignissen überrascht und zu Opfern Schwarzer Schwäne werden.

Nach Talebs Definition ist ein Schwarzer Schwan ein nicht vorhersehbares Ereignis mit drastischen Folgen, die sowohl positiv wie auch negativ sein können. Üblicherweise nehmen wir jedoch nur die Schwarzen Schwäne mit negativen Folgen wahr. Dem liegt ein Denkmuster zugrunde, das die Grundlage unseres Selbstbewusstseins ist. Entwickelt sich etwas stark positiv, führen wir das auf unsere Fähigkeiten zurück. Im umgekehrten Fall suchen wir nach einer externen Ursache für die negative Entwicklung – wir glauben, dass wir einfach Pech hatten.

Beide Betrachtungen sind uns als Menschen von Natur aus zu eigen, in komplexen Systemen aber gleichermaßen falsch. In der Softwareentwicklung verarbeiten wir Wissen und erstellen daraus komplexe Systeme, die uns bei intellektuellen Prozessen unterstützen. Im Gegensatz zu vielen anderen Tätigkeiten ist diese Tätigkeit nicht nur von unseren Fähigkeiten in der Programmierung abhängig, sondern auch von unserem Verständnis der Wissensdomäne für die wir Software entwickeln. In der Welt der Softwareprojekte sind diese Wissensdomänen häufig von Projekt zu Projekt so unterschiedlich, dass wir von unseren Erfahrungen nur in sehr geringem Maß profitieren können. Als Resultat sind wir in jedem Projekt aufs Neue einem Lernprozess ausgesetzt, den Phillip G. Armour mit seinen Five Orders of Ignorance zusammenfasst (siehe: Armour, Phillip G.: „The Laws of Software Process“):

  • 0th Order of Ignorance (0OI) – Lack of Ignorance: Die erste Stufe von Unwissen bedeutet, dass man über sicheres Wissen verfügt. Ein typischer Fall von 0OI ist sein eigenes Geburtsdatum. Das kennen die meisten Menschen sehr genau.
  • 1st Order of Ignorance (1OI) – Lack of Knowledge: Auf der zweiten Stufe des Unwissens fehlt eine Information. Man weiß aber sehr genau, wie man diese Information beschaffen kann. Als Beispiel mag die Telefonnummer eines Kollegen dienen. Wenn man sie nicht auswendig gelernt hat, kann man sie im Adressbuch der Firma nachschlagen.
  • 2nd Order of Ignorance (2OI) – Lack of Awareness: Die dritte Stufe des Unwissens beschreibt das Fehlen von Wissen darüber, welche Informationen fehlen. Man weiß nicht, was man nicht weiß. Für diese Stufe ist es naturgemäß schwierig, ein gutes Beispiel zu liefern, darum stattdessen ein Zitat unbekannter Herkunft: Wenn wir wüssten, was wir nicht wissen, wüssten wir es schon.
  • 3rd Order of Ignorance (3OI) – Lack of Process: Gibt es zusätzlich auch keinen bekannten Weg, über den herausgefunden werden kann, ob es etwas gibt, von dem man nicht weiß, dass man es nicht weiß, befindet man sich auf der vierten Stufe des Unwissens.
  • 4th Order of Ignorance (4OI) – Metaignoranz: Die fünfte und letzte Stufe des Unwissens beschreibt letztendlich die Tatsache, dass nicht bekannt ist, dass die Five Orders of Ignorance existieren.

Die Schwierigkeit dieses Lernprozesses liegt darin, dass wir für ein Projekt zu Beginn in der Regel einen Plan aufstellen müssen. Planung kann allerdings nur mit Unwissen der 0OI und der 1OI umgehen. Eine neue Wissensdomäne befindet sich aber zunächst auf der 2OI oder – gerade zu Beginn eines Projekts – auf der 3OI. Da Pläne nicht über die 1OI hinaus erstellt werden können, befinden sie sich üblicherweise auf der 4OI. Unsere übliche Lösung, „unknown Unknowns“ zu kompensieren, besteht in der Einplanung von Puffern. Deren Größe leiten wir aus den Aufwänden der Anforderungen ab, die sich auf Ebene der 0OI oder 1OI befinden. Da es zwischen den Größen der Anforderungen auf der 0OI und der 1OI und denen auf der 2OI  keinen systematischen Zusammenhang gibt, sind negative Schwarze Schwäne vorprogrammiert.

Das Spezifikationsdilemma und vorausschauende Programmierung

Natürlich spüren wir instinktiv, wenn wir einen solchen Plan sehen, dass es dabei ein Problem gibt, wir sind nur nicht dazu fähig, es zu formulieren – das Problem befindet sich ja auf der 2OI. Unsere Reaktion auf eine solche Unsicherheit besteht darin, alles an Wissen zu sammeln, das wir sammeln können. Wir spezifizieren das Ziel unseres SoftwareProjekts mit dem Wissen, das wir haben (0OI), und beschaffen die Antworten auf die Fragen, die wir kennen (1OI). Das funktioniert sehr gut und führt in den meisten Projekten auch zu validen Ergebnissen. Allerdings reicht es nicht, um die Unsicherheit zu eliminieren. Das wissen wir, und deshalb tauchen in vielen Lastenheften Anforderungen auf, die fordern, dass die zu entwickelnde Software auch mit zukünftigen Anforderungen umgehen können oder so beschaffen sein muss, dass Komponenten wiederverwendbar sind. Steht das nicht im Lastenheft, gibt es mindestens eine Architekturvorgabe dazu. Die Unsicherheit, die durch die 2OI ins Projekt kommt, wird auf eine technische Ebene delegiert. Ich bezeichne das als Spezifikationsdilemma.

Eine Folge dieses Dilemmas, die sich bis in die Didaktik der Informatik durchgeschlagen hat, ist der Drang von Softwareentwicklern, in Fällen großer Unsicherheit generische Lösungen mit einem hohen Grad an Abstraktion zu schaffen. Die Argumente dafür sind häufig, zukünftige Aufwände durch Vorausdenken einzusparen oder Anforderungen, die vielleicht noch kommen mögen, bereits zu berücksichtigen. Unglücklicherweise ist das vermeintliche Voraussehen von Anforderungen eine der größten Fallen, in die Softwareentwickler tappen können. Dieser Versuch, dem Spezifikationsdilemma zu entkommen, zeigt sehr schön, wie schwer es uns fällt, mit der 2OI umzugehen.

Die einzige Möglichkeit zum Umgang mit der 2OI, die Softwareentwickler sehen, besteht in der Flucht nach vorn – nämlich auf die beschriebene Weise Fakten zu schaffen. Diese eingeschränkte Perspektive liegt daran, dass Entwickler in solchen Situationen häufig im 4OI-Modus denken, sie sich also nicht über die Five Orders of Ignorance im Klaren sind. Das ist nicht ganz ungefährlich. Im Fall von technischen Themen besteht das Risiko, dass Entwickler gerade mit dem Versuch vorauszuschauen die Grundlage für Schwarze Schwäne legen oder sie verstärken.

Mit etwas Abstand wird deutlich, dass es eine zweite Möglichkeit gibt, mit der 2OI umzugehen. Sie besteht darin, das Gegenteil des oben Beschriebenen zu tun und so wenige Fakten wie möglich zu schaffen und gerade nicht zu versuchen, mögliches späteres Wissen (die heutigen 2OI) mit Mitteln der 0OI oder 1OI vorauszusehen. Das fällt uns nicht leicht, werden doch Vorausschauen und wohl durchdachte Strukturen unter Softwareentwicklern als Qualität betrachtet. Dabei kann die Zeile Code, die nicht geschrieben wurde, die beste von allen sein, denn sie erlaubt es, Optionen zu erhalten.

Die Kunst der Optionen

Die erste schriftliche Erwähnung einer Option findet sich in Aristoteles’ Politik [4]. In dieser Anekdote geht es um Thales von Milet, einen griechischen Philosophen und Mathematiker. Die Geschichte beginnt mit einer Diskussion zwischen Thales und einigen seiner Bekannten, die alle einen gewissen Wohlstand erreicht hatten. Ihrer Meinung nach war Thales nicht fähig, solchen Wohlstand zu erreichen, weshalb er Philosoph wurde. Thales bewies ihnen das Gegenteil.

Die gesamte Region um Milet lebte von der Olivenernte und der Herstellung von Olivenöl. Thales schloss einen Vertrag mit den Besitzern aller Olivenpressen in der Gegend um Milet, der ihm für ein geringes Entgelt ein Vorzugsrecht auf die Benutzung der Pressen einräumte. Zurzeit der Olivenernte übte Thales dieses Recht aus und machte als Untervermieter der Olivenpressen stattliche Gewinne.

Aristoteles, der Thales’ Geschichte dokumentierte, unterlag einer groben Fehleinschätzung. Er vermutete, dass Thales’ Erfolg auf dessen Wissen über den Erfolg der Olivenernte zurückzuführen sei. Dabei spielte Wissen in der Geschichte überhaupt keine Rolle. Das einzig relevante war die Asymmetrie des Vertrags, den Thales mit den Besitzern der Ölpressen geschlossen hatte. Mehr noch: Da die Olivenernte ein zukünftiges Ereignis war, konnte Thales allenfalls auf Indizien zurückgreifen, keinesfalls aber auf faktenbasiertes Wissen. Wissen über noch nicht stattgefundene Ereignisse ist immer 2OI. Aristoteles hat, wie viele nach ihm, den Kern der Geschichte verkannt.

Tatsächlich sicherte sich Thales durch das Schaffen von Optionen (eben der Option, die Olivenpressen bevorzugt nutzen zu dürfen) gegen sein Unwissen (wie wird die Olivenernte ausgehen) ab. Der Preis für die Absicherung war gering, der potenzielle Gewinn hoch. Thales hatte das Prinzip der Asymmetrie von Optionen und ihrer Möglichkeit, mit Unwissen umzugehen, verstanden.

Wie kann Thales’ Ölpressenvertrag auf die Softwareentwicklung übertragen werden? Die Antwort darauf besteht in der Übertragung der Asymmetrie.

Im Falle von Thales liegt eine sehr erfolgreiche Asymmetrie vor. Der Gewinn (durch das Weitervermieten der Ölpressen) überstieg die möglichen Verluste (Kosten der Option auf die bevorzugte Benutzung der Ölpressen) um ein Vielfaches (Abb. 1). Mehr noch: Thales gelang es, seine Verluste absolut zu begrenzen. Im Fall einer Missernte hätte er lediglich die Kosten der Option tragen müssen. Seine Gewinne hingegen waren nicht begrenzt, er konnte die Olivenpressen zu einem beliebigen Preis entsprechend der Nachfrage weitervermieten. Diese Asymmetrie schützte Thales vor Verlusten und ermöglichte ihm Gewinne, ohne dass er wusste, wie die Olivenernte ausfallen würde. Thales akzeptierte sein Unwissen über die Zukunft und nutzte Asymmetrie, um eine Option zu schaffen, durch die er von unsicherem Wissen profitieren konnte.

Abb. 1: Asymmetrie eines Gewinns – Thales nahm geringe sichere Verluste in Kauf

Abb. 1: Asymmetrie eines Gewinns – Thales nahm geringe sichere Verluste in Kauf

Neben dieser erfolgreichen Asymmetrie, die auf Optionen basiert, gibt es auch ihr Gegenteil: eine Asymmetrie, die versucht, Gewinne frühzeitig zu sichern und dafür auf Optionen verzichtet. Diese Art von Asymmetrie kann im Resultat zu Verlusten führen, die die zu erwartenden Gewinne drastisch übersteigen. Ein Beispiel hierfür ist die „Pöppenrader Ernte“ in Thomas Manns Buddenbrooks (siehe: Mann, Thomas: „Buddenbrooks“, Teil 8, Kapitel 2 ff.). Hier schlägt Tony Buddenbrook vor, das gesamte Getreide bis zum letzten Halm noch vor der Ernte zu kaufen. Ihre Absicht ist, damit den Gewinn aus dem späteren Verkauf zu sichern. Als dann die Ernte durch ein Unwetter vernichtet wird (ein Schwarzer Schwan), ist nicht nur das bereits bezahlte Geld verloren, sondern auch die erhofften Gewinne. Die vermeintliche Sicherung der Gewinne führte zu ihrer vollständigen Vernichtung (Abb. 2).

Abb. 2: Asymmetrie eines Verlusts – Tony Buddenbrook sicherte Gewinne und riskierte einen Totalverlust

Abb. 2: Asymmetrie eines Verlusts – Tony Buddenbrook sicherte Gewinne und riskierte einen Totalverlust

In Softwareprojekten verhalten sich viele Menschen wie Tony Buddenbrook. Die oben beschriebene Flucht nach vorn ist nichts anderes, als der Versuch, potenzielle Gewinne frühzeitig zu sichern. Das liegt unter anderem daran, dass Menschen nach kurzfristigen Belohnungen streben und diese durch das gefühlte Sichern eines Gewinns erreicht werden. Das Erhalten von Optionen in der Softwareentwicklung wird hingegen nur langfristig belohnt, weshalb es für Menschen weniger erstrebenswert ist. Dazu kommt, dass im Nachhinein nicht auf den ersten Blick zu unterscheiden ist, ob die Probleme durch die Anforderung aus zu viel geschaffenen Fakten oder zu wenigen resultiert. Diese Erkenntnis benötigt eine intensive Recherche, für die in den meisten Projekten keine Zeit besteht.

Dabei ist gerade der Mangel an Zeit in Softwareprojekten ein Grund, so viele Optionen wie nur möglich zu erhalten.

Agilität und Optionen

Wie können in einem Softwareprojekt, das immer Einschränkungen hinsichtlich Budget und Zeit unterliegt, Optionen erhalten werden? Die Antwort liegt im konsequenten Vermeiden der oben beschriebenen Flucht nach vorn. Software ist ein komplexes System, und als solches folgt ihre Entwicklung keinen linearen Gesetzmäßigkeiten.

Als Beispiel dient das Thema Performance, das mir bisher in jedem Softwareprojekt begegnet ist. Sofern ich Einfluss darauf habe, halte ich mich immer an die Devise: „First make it run, then make it fast“. Entsprechend schneide und priorisiere ich auch Anforderungen. Ist die Funktionalität fertiggestellt, hole ich Feedback von den Anwendern ein und lasse sie entscheiden, ob die Performance ausreicht. Da das in der Mehrzahl der Fälle so ist (die gefühlte Performance kann deutlich höher sein als die gemessene), muss mein Team die zweite Anforderung (make it fast) gar nicht mehr umsetzen – ein Gewinn für das gesamte Projekt, denn nun kann sich das Team mit der nächsten Funktionalität beschäftigen. Nebenbei: Auf diesem Weg spart man sich auch die Diskussion mit Auftraggebern darüber, dass sie gar nicht im Stande seien, Performance mit Zeiteinheiten anzugeben. Das sind sie wirklich nicht. Performance ist häufig 2OI, bis Menschen mit einer Software arbeiten.

Sehr oft passiert es, dass Entwickler meinen, es sei Quatsch, Anforderungen auf diese Weise zu priorisieren. Die Argumente folgen dann immer dem Schema, dass wenn man „es gleich richtig macht“ im Nachhinein viel Aufwand gespart würde. Das stimmt auch manchmal, nur eben nicht bei der Mehrheit der Fälle. Die Optimierung der Performance von Software geht immer mit einer Zunahme ihrer Komplexität einher. Komplexität verursacht Aufwand, und dessen Abschätzung ist ein Problem der 2OI. Wenn es nicht möglich ist, diesen Aufwand zu bestimmen, wird es schwierig, zu ermitteln, wie groß die erreichte Einsparung ist. Deshalb ist das vermeintliche Einsparen von zukünftigen Aufwänden kein valides Argument, auf Optionen zu verzichten. Abgesehen davon ist so eine Aussage auch nicht falsifizierbar und taugt deshalb nicht als Argument. Dazu kommt, dass noch nicht klar ist, ob die Aufwände für die schnelle Lösung in Zukunft überhaupt geleistet werden müssen. Diese Frage ist definitiv auf der 2OI anzusiedeln. In solchen Fälle sollte nicht Tony Buddenbrook, sondern Thales als Beispiel dienen. Die Option des „then make it fast“ zu erhalten, ist in jedem Fall erstrebenswerter als die des „first make it run“ aufzugeben.

Auch wenn hier das Thema Performance im Vordergrund stand, lässt sich dieses Prinzip auf sehr viele nicht funktionale Anforderungen anwenden, die sich auf die Komplexität von Software auswirken. Das Gleiche gilt für vermutete zukünftige funktionale Anforderungen.

Auf dem Weg zur Antifragilität

Das Prinzip der Antifragilität beschreibt ein System, das durch einen Schwarzen Schwan nicht beschädigt oder zerstört wird, sondern von ihm profitiert (Abb. 3). Antifragilität profitiert von Optionen und vermeidet die lineare Prognose der Zukunft. Insofern hat sich Thales im Sinne der Antifragilität verhalten, Tony Buddenbrook entgegengesetzt.

Abb. 3: Fragile, robuste und resiliente Systeme – beim Auftreten eines Schwarzen Schwans werden fragile und robuste Systeme zerstört, resiliente Systeme erholen sich, antifragile Systeme profitieren

Abb. 3: Fragile, robuste und resiliente Systeme – beim Auftreten eines Schwarzen Schwans werden fragile und robuste Systeme zerstört, resiliente Systeme erholen sich, antifragile Systeme profitieren

Seit Talebs Buch erschienen ist, häufen sich die Dokumente zu der Frage, wie Software beschaffen sein muss, um antifragil zu sein. Insbesondere Verfechter von Microservices thematisieren Antifragilität und sehen Microservices als Implementierung einer antifragilen Softwarearchitektur. Dass dem nicht so sein kann, wird spätestens dann deutlich, wenn Taleb sagt: „Technology is inherently fragile“.

Software als Technologie kann selbst nicht antifragil sein, sie kann nur in Zusammenhang mit ihrem Entstehungsprozess dem Prinzip der Antifragilität genügen – nämlich dann, wenn bei ihrer Entstehung viele Optionen erhalten wurden. Eine solche Betrachtung erfordert ein Umdenken bei der Planung von Softwareprojekten ebenso wie beim Entwurf von Softwarearchitekturen. Diese Aufgaben müssen sich hin zu Management und Erhaltung von Optionen wandeln.

Dieses Erhalten von Optionen wird in Zukunft eine der größten Herausforderungen für Softwarearchitekten sein. Die kontinuierliche Weiterentwicklung einer Software führt zwangsläufig zu einem stetigen Verlust an Optionen, da jedes neue Feature und jedes neue Modul Fakten und Komplexität schafft. Softwarearchitekten werden sich daher intensiver mit der Frage nach dem letztmöglichen Zeitpunkt einer Entscheidung auseinandersetzen müssen, als mit der Entscheidung selbst.

Aufmacherbild: Black Swans via Shutterstock.com / Urheberrecht: imagevixen

Geschrieben von
Gerrit Beine
Gerrit Beine
Gerrit Beine ist Managing Consultant bei der adesso AG mit den Schwerpunkten Agilität und Softwarearchitektur. Er ist regelmäßig als Sprecher auf Konferenzen zu treffen und beschäftigt sich gerne mit außergewöhnlichen Fragestellungen zur Softwareentwicklung.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.