Follow my new blog

Sonntag, 4. September 2011

Voraussetzungen für sich entwickelnde Softwarestrukturen

Liegt die Zukunft der Softwarearchitektur in Emergent Architecture und Growing Software? Diese Frage wurde in zwei Open Space Gruppen auf der SoCraTes Konferenz 2011 behandelt. Das hat mir gefallen, da ich ja mit meinen Softwarezellen auch schon einmal eine naturnahe Metapher gewählt hatte.

In den Diskussionen wurde ich das Gefühl jedoch nicht los, dass wir bei allem Appeal der Metaphern noch zu wenig darüber nachgedacht hatten, was es denn wirklich heißt, naturnah Software entstehen zu lassen. Wie entwickeln sich natürliche Systeme? Was lässt sich davon auf Softwareentwicklung übertragen? Welche Voraussetzungen sind nötig?

Struktur entspricht gegenwärtiger Umwelt

Ganz zentral für naturnahe Softwareentwicklung ist, dass wir die Rolle der Umwelt richtig verstehen. In der Natur ist alles so wie es ist, weil es so am besten zur Umwelt passt. Das ist der Kerngedanke der Evolutionstheorie, würde ich sagen. Alles an allen Organismen hat einen Zweck, den es erfüllt, so wie es ist. Da ist nichts zuviel, nichts zuwenig.

Vor allem ist nicht so entwickelt wie es ist auf Vorrat. Alles ist nur einer gegenwärtigen Umwelt mit ihren über Generationen erfahrenen Schwankungen angepasst. Kein Lebewesen besitzt eine Eigenschaft nach dem Motto “Aber was wäre, wenn Umweltparameter X in der Zukunft ganz anders aussehen würde?”

Leben ist insofern “lean”, d.h. frei von “Fett”. Es gibt keine “Eigenschaftenpolster”. Selbst die Anpassungsfähigkeit ist begrenzt, obwohl sie die wichtigste Metaeigenschaft ist.

Wenn wir wirklich naturnah Software entwickeln wollen, dann müssen wir konsequent auf den Blick in die Glaskugel verzichten. Erfahrung, die uns verleitet zu sagen, “Aber ich weiß doch, dass Kunden in den meisten Fällen noch Y wollen…”, darf nicht zu Anreicherungen in der Software führen. Das höchste der Gefühle ist, dem Kunden einen solchen Gedanken vorzulegen, um durch seine Antwort die gegenwärtige Umwelt besser zu verstehen. Das oberste Prinzip naturnaher Entwicklung ist mithin YAGNI.

Jede Entscheidung darf sich nur vom gegenwärtigen Kenntnisstand leiten lassen. Dann ist die Entscheidung erstens schnell getroffen und zweitens das Ergebnis so schlank wie möglich.

Evolution ist ohne Ziel

Wenn Evolution sich nur an der gegenwärtigen Umwelt orientiert, dann bedeutet das in verschärfter Formulierung, dass Evolution kein Ziel hat. Und das bedeutet, Evolution kann nicht vorplanen. Es gibt kein Vordenken, sondern nur Reaktion, Anpassung. [1]

Das bedeutet für die Softwareentwicklung ein viel größere als bisher übliche Konzentration auf das Hier und Jetzt. Geradezu buddhistisch muss für naturnahe Entwicklung gelten “live in the now”.

Weder Strukturen noch Schritte sollten über das unmittelbar Sichtbare und Notwendige hinaus ausgelegt sein. Zu YAGNI tritt KISS als Leitprinzip.

Evolvierbarkeit ist ein Ergebnis von Evolution

Als Ergebnis der Evolution sehen wir vor allem die umweltangepassten Eigenschaften von Lebewesen. Wir haben verstanden, dass diese Eigenschaften sich durch Feedback ausprägen. “Survival of the fittest” nennen wir das. Eigenschaften entstehen und müssen sich gegenüber der Umwelt behaupten. Passen sie nicht, sinkt die Wahrscheinlichkeit zur Weitergabe der Eigenschaften an die nächste Generation; unpassende Eigenschaften sterben aus. Das Feedback der Umwelt ist gnadenlos.

Auf die Software haben wir das inzwischen in Form iterativen Vorgehens übertragen. Wir stellen Software mit bestimmten Eigenschaften her, von denen wir meinen, dass sie zur Umwelt (den Anwendern) passen – und suchen dann das Feedback der Umwelt. So nähern nähern wir die Eigenschaften in kleinen Schritten der Umwelt an bzw. co-evolvieren Software mit der Umwelt.

Hinter den sichtbaren Eigenschaften evolvierender Systeme gibt es allerdings noch eine unsichtbare Eigenschaft: die Evolierbarkeit. Wie jede Eigenschaft unterliegt auch sie einem Zwang zur Passgenauigkeit.

Meinem Empfinden nach haben wir diese Eigenschaft als ebenfalls zu entwickeln nicht auf dem Zettel. Wir unterwerfen sie in unseren Projekten keinem Feedback. Wir unterwerfen sie nicht einmal branchenweit einem Entwicklungsdruck (oder allenfalls einem nur vergleichsweise schwachen).

Wenn wir über naturnahe Softwareentwicklung sprechen, ist das eine große Nachlässigkeit, da im Kern der gesuchten Naturnähe ja gerade die Evolvierbarkeit steht.

Wie müsste also das Feedback aussehen, um Evolvierbarkeit zu entwickeln?

Ob unsere Software schon performant, skalierbar, sicher genug ist, stellen wir fest, indem wir sie immer wieder auf die Probe stellen. “Los, zeig uns, wie schnell du bist!”, “Ha! Kommst du auch mit dieser größeren Nutzerlast zurecht?”, “Nimm diese Sql Injection Attacke, du Software, du!”

Aber wie ist es mit der Evolvierbarkeit? Was ist eine Herausforderung für sie?

Ich denke, das sollte auf der Hand liegen: Evolvierbarkeit wird durch unerwartete Anforderungen auf den Grill gelegt. “Pass dich dieser überraschenden Anforderung an, Code!”

Das erste, was Evolution lerne musste war die Unvorhersehbarkeit der nächsten Umweltveränderung. Von der hat sie ihre grundlegenden Bausteine, die Moleküle (DNA, RNA), Organellen und Zellen formen lassen. So existiert Leben am tiefsten Meeresgrund genauso wie im Darm und auf dem Mount Everest.

Für die Softwareentwicklung ist das noch eine Aufgabe, denke ich. Unsere grundlegenden Bausteine sind noch nicht wirklich evolutionsunterstützend. Allemal können wir noch viel zu leicht anti-evolutionäre Strukturen damit herstellen, wie die Massen an Brownfield-Code zeigen.

Das bedeutet, wir müssen mehr Druck auf die Evolvierbarkeit ausüben. Sonst hinkt ihre Entwicklung der anderer Eigenschaften hinterher – und behindert deren Evolution. Wir müssen also geradezu auf die Evolvierbarkeit zuallererst Evolutionsdruck ausüben, weil sie für alles andere fundamental ist. Wie soll das aber geschehen?

Nach meinem Gefühl ist das gar nicht schwer. Wir müssen erstens die Frequenz der Änderungsanforderungen drastisch erhöhen. Und zweitens müssen wir die Vorausschau drastisch begrenzen.

Ganz konkret bedeutet das für mich: Software ist jeden Tag mit überraschenden Änderungswünsche zu konfrontieren. Und jeden Tag ist Software auszuliefern. Nur so entsteht auf ihre Anpassungsfähigkeit soviel Druck, dass die wirklich geschmeidig wird. Das gilt für die allgemeine Form von “Softwarebauteilen” wie für die konkrete Struktur einer Lösung. Ohne diesen Druck werden wir nicht dahin kommen, die Prinzipien und Praktiken für dauerhafte Evolvierbarkeit zu erkennen und zu leben.

Evolution geht aufs Ganze

Wer hätte je einen Magen oder ein Gehirn oder eine Hand getrennt von einem Lebewesen sich entwickeln sehen?

Evolution findet immer am ganzen Organismus statt. Ein Lebewesen ist entweder als Ganzes an seinem Umwelt angepasst oder gar nicht. Das beste Herz nützt nichts, wenn das Nervensystem unangepasst ist.

Auf die Softwareentwicklung übertragen bedeutet das, es gibt keine Infrastrukturentwicklung. Jedes Mal, wenn sich Software der Umwelt aussetzt – also am Ende einer Iteration –, setzt sie sich als Ganzes aus. Sonst ist sie nicht “anschlussfähig” gegenüber ihrer Umwelt. Das muss sie aber sein, sonst bekommt sie kein Feedback. Und Mangel an Feedback bedeutet Stillstand und dann Tod.

Alle Arbeit an Software muss deshalb sagen können, inwiefern sie an die Umwelt anschließt, welches konkrete Bedürfnis der Umwelt sie erfüllt. Ein Team als Ganzes muss zu jeder Zeit auf die Software als Ganzes konzentriert sein. (Ein einzelner Entwickler kann sich im Rahmen dessen natürlich auf ein Detail fokussieren. Er dient damit ja einem Ganzen.)

Naturnahe Entwicklung bedeutet also Entwicklung in Durchstichen. In jeder Iteration ist eine ganze, besser angepasste Software abzuliefern. [2]

Evolution ist Verfeinerung

Schließlich scheint mir ein wesentliches Merkmal von natürlicher Entwicklung die Bewegung vom Groben zum Feinen. Evolution ist Differenzierung, ist Verfeinerung.

Die Entscheidung zwischen bottom-up und top-down Entwicklung können wir zur Ruhe betten. Diese beiden Pole sind unwichtig. Wir können die Herangehensweise wählen, wie wir mögen, wie es uns in Bezug auf eine Problemstellung passt.

Worüber wir aber nicht nachdenken sollten, das ist coarse-to-fine oder simple-to-complex Entwicklung. Software sollte schrittweise “schärfer” oder detaillierter werden.

Auch breadth-first vs. depth-first ist hier zweitrangig. Die Verfeinerung kann in der Breite in geringem Maß stattfinden oder in der Tiefe in hohem Maß. Wie es der Kunde mag. Er bestimmt die Prioritäten.

Nach jeder Iteration kann er sich wünschen, ob Feature A verfeinert werden soll oder lieber Feature X grob angegangen werden soll. Vor dem Hintergrund des täglichen Drucks auf die Evolvierbarkeit bedeutet das, der Kurs der Entwicklung kann sich prinzipiell jeden Tag ändern. Und warum auch nicht? Der Kunde, die Anwender: das ist die Umwelt. Der gilt es sich anzupassen.

Naturnahe Entwicklung findet deshalb in kleinsten Schritten statt. User Story, Use Case, ja selbst Feature sind dafür zu groß. Würden sie pro Iteration komplett umgesetzt, würde zu schnell zu viel Detail entstehen. Das wäre keine Evolution mehr, sondern Setzung.

Wenn es jedoch jeden Tag an quasi beliebiger Stelle in der Software ein Nutzenstückchen weiter geht, dann entsteht kontinuierliche Anpassungsfähigkeit. Dann kann auch nie mehr als die Arbeit eines Tages umsonst gewesen sein. Tägliches Feedback korrigiert ja den Evolutionsweg unmittelbar.

Fazit

Agile Softwareentwicklung ist schon ein Schritt in Richtung naturnahe Softwareentwicklung. Erreicht ist das Ziel mit ihr jedoch noch nicht. Wenn wir naturnahe Softwareentwicklung als Tugend ansehen, dann müssen wir ein paar Schrauben noch mehr anziehen. Evolution ist rigoroser als Agilität.

Fußnoten

[1] Ziellosigkeit mag merkwürdig klingen, da doch anscheinend mindestens der Kunde ein Ziel hat. Er möchte schließlich eine Software für einen bestimmten Zweck. Wie oft ist es aber der Fall, dass am Ende der Entwicklung genau das herauskommt, was am Anfang in den Anforderungen drin gestanden hat? Wie oft sind Anforderungen vollständig? Ich halte es deshalb für besser, die Idee von der Zielhaftigkeit im Sinne einer sichtbaren Zielmarke aufzugeben. Softwareentwicklung ist vielmehr ziellos – hat jedoch ein Ende. Beendet ist sie, wenn der Kunde sagt “Genug!”

[2] Mit “ganze Software” meine ich natürlich nicht, dass vom ersten Tag an eine komplette Buchhaltung oder eine ganze Textverarbeitung ausgeliefert werden soll. Wie sollte das auch gehen? Nein, “ganze Software” bedeutet, dass die Software für den Anwender als etwas sinnhaftes wahrnehmbar ist, zu dem er Feedback geben kann. Für eine Buchhaltungssoftware bedeutet das nicht mal, dass es ein GUI geben muss, sondern am ersten Tag vielleicht nur einen Prüfstand, mit dem der Anwender Feedback zum Datenimport geben kann.

Spendieren Sie mir doch einen Kaffee, wenn Ihnen dieser Artikel gefallen hat...

Kommentare:

Thomas Gey hat gesagt…

Hallo Ralf,
ich finden den Artiekl super, er trifft im Kern auch meine Sicht auf die Softwareentwicklung. Ich denke aber nicht, dass die Evolution kein Ziel hat. Das Ziel der Evolution ist ja das Leben an sich. Das (über)Leben in einer Umwelt die sich ständig verändert. Von C. Darwin stammt auch folgendes Zitat: "Nicht die stärksten oder die intelligentesten Spezies werden überleben, sondern diejenigen, die sich am schnellsten anpassen."... und warum sollte dies Metapher nicht auch auf das "Leben" von Programmen / Software zutreffen ?
Gruß Thomas

Christian Jacob hat gesagt…

Moin Ralf,

Da mein Kommentar für Deinen Blog zu lang war (> 4096 Zeichen), wurde daraus kurzerhand ein eigener Blogeintrag quasi als Reaktion auf Deinen. :)

http://blog.toptechnologies.de/post/Evolvierbare-Software-Geschlossen-fur-Erweiterung-Offen-fur-Veranderung.aspx

Viele Grüße,
Christian.

Thomas Gey hat gesagt…
Dieser Kommentar wurde vom Autor entfernt.
Ralf Westphal - One Man Think Tank hat gesagt…

@Thomas: Genau, es geht um "schnelle Anpassung"; wobei die Geschwindigkeit natürlich nur angemessen sein muss. In einer sich nur langsam verändernden Umwelt muss man sich nicht so schnell anpassen.

Wie schnell ist aber für Software schnell genug?

Angesichts dessen, dass Kunden ihre Anforderungen nicht genau kennen, sich ihre ungenauen Anforderungen ohne unser Zutun jederzeit ändern können und Software & Kundenwelt in einer Co-Evolution befinden, sollten wir uns nicht vorschnell zufrieden geben. Den Punkt, wo wir sagen können, "Ach, so schnell müssen wir uns nicht anpassen können", haben wir noch nicht erreicht.

Deshalb glaube ich eben, dass wir täglichen Änderungsdruck brauchen. Scrum ist lasch mit seinen mehreren Wochen währenden Iterationen. Und bei Kanban gibt es gar keinen Druck; jede Aufgabe kann bei ihrer Station so lange verweilen wie nötig.

Da entsteht einfach kein Druck auf die Evolvierbarkeit. Wir bekommen zuwenig Feedback für sie. Deshalb kommen wir bei ihrer Entwicklung nur schleppend voran. SOLID ist bei weitem nicht genug.

Thomas Gey hat gesagt…

Hallo Herr Jacob,
ich habe Ihren Beitrag ebenfalls gelesen. Ich sehe für mich keine Unvereinbarkeit von einer "natürlichen" Softwareentwicklung und dem OCP. Ich sehe die Evolvierbarkeit (die Fähigkeit von Software(-modulen,-architekturen,-...) sich neuen Anforderungen anzupassen) eher als eine Art "digitales" Naturgesetz. Dieses wirkt auf alle Elemente der Softwareentwicklung, also nicht nur Code, sondern auch auf Methoden, Prozesse, Qualitätssicherung (Tests) und villeicht sogar Organisationsstrukturen. So jetzt kommt meine (villeicht ketzerische) Hypothese. Der Ansatz für einen neue Denkweise in der Softwareentwicklung wäre wie bei anderen Naturgesetzen, einfach die Akzeptanz des Naturgesetzes ,also die Anerkennung als Realität. Dadurch findet es sofort Berücksichtigung in allen Belangen des Softwareentwicklungsprojektes. Ob es um die Gestaltung von Code geht, wo zugleich auch OCP berücksichtigt werden kann oder um die Einführung einen ChangeRequest Prozesses mit dem Kunden. Der für Kunden und Entwickler die Bearbeitung von Änderungswünschen im gleichen Maß transparent gestaltet.

Gruß Thomas

Daniel Dietrich's Blog hat gesagt…

Hallo,

der Artikel ist sehr inspirierend. In der Mathematik würde man sagen, dass solch ein Vorgehen kanonisch ist bzw. natürlich, eben der Natur entsprechend. Die Natur strebt fortlaufend nach Ausgleich. Jeder Spieler hat einen Gegenspieler, Materie/Antimaterie, Anabolismus/Katabolismus, Aktivität und Ruhe [1]. Da die Natur perfekt ist, findet der Ausgleich in optimaler Weise statt. Die Bedeutung des Begriffes optimal hängt dabei von der Umgebung bzw. dem Kontext ab, den man betrachtet. Ein Projektleiter wird beispielsweise fordern, dass ein Projekt inkl. aller Unschärfen und Risiken planbar ist. Dazu muss man das Ziel kennen und vorausschauend handeln. Die Evolution endet jedoch nie (bzw. absehbar), da sich nicht nur in der Natur, sondern auch in Projekten die Umgebungsbedingungen stetig ändern. Betrachtet man die Evolution der Software ganzheitlich, so stellt das Projekt lediglich die Geburt der Software dar, oder vielmehr einer Art von Software. Denn es muss nicht unbedingt immer dieselbe Struktur sein, die schrittweise bzw. iterativ angepasst wird. Auch Software besitzt eine Lebenszeit. Das Wissen geht nach dem Ableben einer Software nicht verloren, sondern fließt in neue Software ein. Gute Gene werden in diesem Sinne weitergegeben.

Viele Grüße aus Kiel

Daniel Dietrich

Fußnote [1]: Sieht man die Zustände 0 und 1 auch als natürlich an, so kann man davon ausgehen, dass unsere Maschinen inkl. der darauf laufenden Anwendungen bereits Teil der Evolution sind.

Oezcan hat gesagt…

"Naturnahe Entwicklung bedeutet also Entwicklung in Durchstichen. In jeder Iteration ist eine ganze, besser angepasste Software abzuliefern."

Was eignet sich da besser als BDD.

Timm Krause hat gesagt…

Hallo,

sehr interessanter Artikel, vielen Dank für die Eindrück!

Ich formuliere das jetzt bewußt provokativ und bin gespannt was ihr davon haltet:

1. Eine Abstraktionsebene höher: Ist Softwareentwicklung an sich nicht bereits so, wie sie am besten in Ihre Umwelt passt? Derzeit gibt es auch nicht zuviel und nicht zu wenig. Sie passt sich bereits den äußerlichen Einflüssen (Anforderungen) an und entwickelt sich auf diesen basierend weiter.

2. Würde man mit diesem Ansatz nicht auch die negativen Aspekte der naturgemäßen Anpassung implementieren? Evolution/Veränderung dauert lange (und erzeugt ggf. Overhead?), ohne "Eigenschaftenpolster", ohne vorauszudenken.


Gruß

Timm

Ralf Westphal - One Man Think Tank hat gesagt…

@Oezcan: BDD passt zu naturnaher Entwicklung. Klar. Aber BDD allein ist keine Lösung. BDD macht keine Aussage über die Granularität, in der man entwickeln soll. Es fehlt deshalb Druck. Der muss von anderer Seite dazu kommen.

@Timm: Ja, man kann die heutige Softwareentwicklung als angepasst beschreiben. Irgendwie funktioniert es ja. Das bedeutet aber nicht, dass der "Energieaufwand" nicht sinken kann.

Sinkt der nämlich nicht, hat die Softwareentwicklung keine Reserven. Verändert sich die Umwelt mal stärker, dann stürzt sie ab.

Mehr Evolvierbarkeit, flüssigere Produktion zielen also darauf ab, die Spielräume zu erhöhen.

Thomas Gey hat gesagt…

@Timm Krause: Ich denke schon das sich einige Teile der Softwareentwicklung diesem Prinzip annähern.z.B. das die Softwareentwicklung in Entwicklungszyklen abläuft (Version 1.0, 1.1, 1.n) am Ende eines jeden Zyklus steht sozusagen die neue Kindgeneration. Wenn man noch tiefer reinschaut entspricht jeder Build einer neuen Kindgeneration. Mit den ausgeführten Tests (automatisch, manuell oder durch den Kunden) wird entschieden welche Version "überlebensfähig" ist. Ich denke das diese Entwicklung der Softwareentwicklungsmethoden, da sie ja durch uns Menschen getragen wurde und wird, bisher eher unterbewusst abgelaufen ist. Da wir ja ebenfalls aus der Evolution hervorgegangen sind und Bestandteil der Natur sind, denke ich, dass diese "natürlichen Prinzipien" in uns enthalten sind und wir besser mit "natürlichen Methoden" klar kommen.