Follow my new blog

Mittwoch, 5. Oktober 2011

Skalierbare Softwarebausteine - Teil 1

Wie können wir Software mit evolvierbarer Struktur herstellen? Wie kann Software selbst so agil werden wie unsere Prozesse es schon geworden sind? Diese Frage treibt mich immer noch um. Die bisher angebotenen Lösungsansätze aus Richtung Clean Code finde ich noch nicht ausreichend. TDD und SOLID sind ganz gute Ansätze… nur fehlt ihnen aus meiner Sicht ein umfassender Blick auf Software. Das SRP in SOLID ist zwar grundlegend – doch DI ist demgegenüber merkwürdig sprachspezifisch, finde ich. Und TDD fokussiert auf Code, so dass von TDD wenig Hilfe zu erwarten ist, wenn noch gar kein Code oder eine Code-Idee vorhanden ist.

Ich glaube deshalb weiterhin, dass wir noch einen Schritt zurücktreten müssen. Wir müssen eine allgemeinere Vorstellung von Software entwickeln, in die dann TDD und SOLID usw. hineinpassen. TDD und SOLID sollen also nicht einfach ersetzt werden, sondern einen soliden Platz bekommen.

Warum die real existierende Objektorientierung uns behindert

Die Objektorientierung, so könnten Sie sagen, ist doch aber schon so eine allgemeine Vorstellung von Software. Ja, das stimmt. Irgendwie ist sie das. Und dann doch wieder nicht. Zumindest nicht die real existierende Objektorientierung, die sich von einer idealen ursprünglichen stark unterscheidet. Die real existierende Objektorientierung (REOO) hat aus meiner Sicht einfach einige große Mängel:

  • Sie REOO skaliert konzeptionell nicht. Wir können Software mit ihr nicht vom kleinsten bis zum größten Baustein durchgängig beschreiben. Dass Software aus Bausteinen unterschiedlicher Größe/Granularität zusammengesetzt ist, sollte außer Zweifel stehen. Damit meine ich nicht, dass Bausteine mal mehr und mal weniger LOC haben. Ich meine ihre konzeptionelle Größe, ihren Funktionsumfang. Eine ganze EXE umfasst mehr Funktionalität als eine Klasse in der EXE.
    Mir fällt es jedenfalls sehr schwer, Software aus Objekten unterschiedlicher Granularität vorzustellen. Der UML offensichtlich auch, sonst würde sie Klassendiagrammen nicht auch noch Komponenten- und Paketdiagramme beistellen. Weder Komponenten noch Pakete gehören jedoch zur Objektorientierung. Wie ihre Namen schon sagen, geht es nicht um Objekte (oder Klassen als deren Schemata), sondern um Komponenten und Pakete.
  • Die REOO ist fixiert auf ein essenziell statisches Bild der Realität. Nomen est omen: Die Realität besteht aus Objekten, aus “Dingern”, die erstmal sind, deren Existenz eine Dauer hat. Diese “Dinger” haben dann vor allem einen Zustand. Die Praxis der REOO versucht sie vor allem anhand von Daten zu identifizieren, für die sie verantwortlich sind. Objekte sind mithin Zuständigkeitsaggregate. Sie bündeln den Umgang mit Daten. Das wird positiv formuliert als Kapselung.
    Ich verstehe, dass diese Sichtweise Appeal hat. Menschen mögen Greifbares. Mit Lego kann jedes Kind umgehen, mit Mathematik jedoch nicht; die ist viel abstrakter. Also mögen Softwareentwickler auch lieber umgehen mit Greifbarem, eben mit Objekten.
    Wenn ich die Wurzel der Softwareentwicklung im Maschinenbau und der Elektrotechnik verorte (und nicht in der Mathematik), dann finde ich das auch nur konsequent. Die vormaligen Hardwarebausteine sind in die Software übertragen worden: aus konkreten Zahnrädern und Hebeln und Transistoren und Widerständen sind Objekte geworden.
    Oder ich könnte philosophisch werden und die Softwareentwicklung an die Griechen binden. Demokrit mit seinen Atomen und Platon mit seinen Ideen haben die Welt bestehend aus klar umrissenen Entitäten aufgebaut gesehen. Die einen waren anfassbar, wenn auch seeeeehr klein. Die anderen abstrakt, dafür beliebig groß. In jedem Fall haben beide ihre “Weltenbausteine” als unwandelbar angesehen, als statische Bausteine.
  • Die REOO verbindet Objekte über Abhängigkeiten. Ein Objekt, das viel kann, ist von Objekten abhängig, die weniger können. Dadurch entsteht eine Abhängigkeitshierarchie, über die die Gesamtleistung vertikal verteilt ist. Auf jeder Ebene passiert ein bisschen.
    Das hat die REOO als Problem erkannt – im Zusammenhang mit der Testbarkeit. Als Gegenmaßnahme empfiehlt sie IoC und DI und Attrappen. Damit werden Objekte auf jeder Ebene einzeln testbar.
    Ich halte das für eine Symptombehandlung. Die Abhängigkeiten bleiben bestehen. Funktionalität ist weiterhin vertikal in der Hierarchie verstreut.

Meine Kritik an der real existierenden Objektorientierung ist also sehr fundamental. Sie macht uns die Beschreibung von Lösungen schwer, weil wir die mit ihren Mitteln nicht leicht auf beliebigen Abstraktionsebenen denken können. Sie fixiert sich auf ein Weltbild, das es uns schwer macht, das zu beschreiben, was Software essenziell repräsentiert: Prozesse. Und die Ergebnisse der Objektorientierung, der Code, hat eine Form, die ganz fundamental anti-agil ist, also im Widerspruch zur zentralen Erkenntnis der Softwareentwicklung steht, dass Software sich ständig anpassen muss.

Aber nun genug des OO-Bashings :-) Es soll nur als Motivationshintergrund dienen, warum ich immer noch und wieder an einem anderen Software-Weltbild bastle. Nicht, dass mit REOO nix ginge. Doch, klar, es geht was. Mit Pferdefuhrwerken ging auch etwas. Jahrhunderte lang. Und dann kam der Trecker. Nun geht noch mehr.

Vorschlag für ein alternatives Weltbild

Damit ich nicht den Anschein erwecke, eine rundum-sorglos Lösung zu bieten – Silverkugeln gibts ja nicht und sind in unserer Branche bei vielen auch nur im Anschein verhasst –, spreche ich lieber mal von einem Traum.

Ja, ich habe einen Traum, in dem wir Software viel einfacher entwickeln. Das ist natürlich auch irgendwie dem verhaftet, was ich in 30 Jahren Softwareentwicklung erfahren habe. Wie Software in 100 Jahren entwickelt wird, kann ich mir wohl nicht vorstellen. Doch für Sie mag mein Traum dennoch esoterisch anmuten. Macht ja aber nichts, ist eben nur ein Traum :-) Träumen Sie doch mal mit. Lassen Sie sich darauf ein. Schicken Sie Ihre Skepsis für eine kleine Weile auf Urlaub. Die kann sich ja mal den Versuchen zur Rettung von Euro und Europa zuwenden.

In meinem Traum entwickeln wir Software anders, weil Software darin ein anderes Weltbild unterliegt. Software oder die Welt besteht darin nicht aus “Dingern”, sondern aus Prozessen. Im Kern steht nicht etwas Statisches, sondern Dynamik. Es geht ums Tun, um Bewegung, um Wandlung. Softwareentwickler fragen nicht, nach “Objekten”, sondern nach “Aktivitäten”.

Nach diesem Weltbild besteht Software aus diesem:

image

Das ist eine Aktivität. Da passiert etwas. Das ist neutral gesprochen eine Funktionseinheit. Kent Beck würde es vielleicht Element nennen.

“Baustein” möchte ich eigentlich ungern dazu sagen, da “Baustein” schon wieder Statik suggeriert wie “Objekt”. Aktion, Aktivität oder eben Funktionseinheit scheinen mir passender.

So eine Funktionseinheit “macht ihr Ding”, indem sie eingehende Daten verarbeitet. Sie steht also für das alte EVA-Prinzip: Eingabe-Verarbeitung-Ausgabe.

Daten können aus verschiedenen Richtungen in die Funktionseinheit einfließen (Input). Das, was sie daraus macht, kann in verschiedene Richtungen aus ihr herausfließen (Output).

Und wenn eine Funktionseinheit nicht reicht, dann arbeiten mehrere zusammen in einem Fluss. Der Output der einen wird zum Input der anderen:

image

Das war´s. So sieht Software aus. Auf jeder Abstraktionsebene. Damit lässt sich eine ganze Anwendung beschreiben wie auch der kleinste Teil einer Anwendung.

Zustand

Input ist ein Trigger für Funktionseinheiten. Kommt Input an, tun sie etwas. Allerdings muss sich eine Aktivität nicht ausschließlich auf einfließenden Input beziehen. Sie kann auch ein Gedächtnis haben, d.h. Zustand. Aus dem kann sie lesen und den kann sie verändern.

Zustand macht es zwar schwerer, über das Ergebnis einer Aktion nachzudenken, aber ich halte Zustand für einen so natürlichen Bestandteil der Welt, dass wir ihn nicht mit Macht ausschließen sollten. Das rückt Funktionseinheiten natürlich in die Nähe von REOO Objekten – doch der Unterschied besteht für mich im Fokus. Bei REOO steht Zustand eher am Anfang, bei meiner Träumerei eher am Ende.

Im einfachsten Fall ist solcher Zustand lokal. Eine Aktion hat individuellen Zustand:

image

Wenn Aktionen kooperieren sollen, dann kann es allerdings nötig sein, dass sie Zustand gemeinsam nutzen. Das ist dann shared state und sollte explizit gemacht werden. Das wird spätestens dann wichtig, wenn der Zugriff darauf gleichzeitig erfolgen soll. Dann muss er nämlich synchronisiert werden.

image

Nebenläufigkeit

Ohne weitere Angaben arbeiten Aktionen sequenziell und synchron. Während eine Funktionseinheit Input verarbeitet, tut das keine andere. Wenn sie Output produziert, stößt sie damit eine empfangende Funktionseinheit an, die ihn als Input verarbeitet, bevor die produzierende weitermacht.

image

Sequenzielle und synchrone Verarbeitung lässt sich gut denken und nachverfolgen. Aber in der realen Welt kommt sie eher nicht vor. Und sie nutzt die verfügbaren Prozessorressourcen womöglich nicht optimal.

Es ist deshalb konsequent, Aktionen auch nebenläufig betreiben zu können. Sie laufen dann auf (mindestens) einem eigenen Thread (und womöglich auf einem eigenen Prozessorkern).

image

Sobald der Fluss von Input-Output durch eine Aktion mit eigenem Thread läuft, findet die weitere Verarbeitung auf diesem Thread statt, bis wiederum eine Aktion mit eigenem Thread angestoßen wird usw.

image

Dass Aktionen nebenläufig betrieben werden können, bedeutet jedoch nicht, dass Nebenläufigkeit auch innerhalb von Aktionen stattfindet. Die scheint mir problematisch, weil sie dazu führt, dass Input in anderer Reihenfolge als der, in der er eintrifft, verarbeitet wird. In meinem Traum ist daher die Verarbeitung innerhalb einer Funktionseinheit immer noch sequenziell. Input wird in der Reihenfolge seines Eintreffens verarbeitet.

Zumindest sollte das wohl der Default sein. Wenn in ganz bestimmten Situationen eine Aktion davon profitiert, in sich ebenfalls nebenläufig zu sein, d.h. Input auf mehreren Threads parallel zu verarbeiten, dann sei das so. Es könnte so ausgedrückt werden:

image

Aktionen sind zunächst also synchron und sequenziell, dann können sie auch asynchron sequenziell sein und schließlich vollständig parallel.

Unabhängigkeit

Es ist vielleicht keiner Erwähnung wert, weil der Fluss von Input-Output es so natürlich macht, doch ich sage es lieber einmal ausdrücklich: Aktionen sind von einander unabhängig.

Zwei verbundene Aktionen wissen nichts von einander. Der Producer (generiert Output) weiß nicht, wer seinen Output weiterverarbeitet. Der Consumer (verarbeitet Input) weiß nicht, von wem sein Input stammt.

Das (!) ist ein fundamentaler Unterschied zur REOO. Und deshalb ist es wohl gut, dass ich ihn hier nochmal betone ;-)

Eine Gesamtleistung als Ergebnis einer Kooperation mehrerer Funktionseinheiten erfordert keinerlei Abhängigkeiten zwischen den Kooperationspartnern. Sie wissen nicht einmal, dass sie kooperieren.

Jede Aktion innerhalb einer “Kooperative” bekommt Input “von irgendwoher” und produziert Output “für unbekannt”.

Ein Zusammenhang von Funktionseinheiten wie dieser:

image

sieht also eher so aus:

image

Schachtelung

Um größere und sehr große Systeme zu beschreiben, müssen Aktionen hierarchisch angeordnet werden können. Aus großer Flughöhe sieht ein System dann eigentlich immer so aus:

image

Wenn man niedriger fliegt, kommen Details in den Blick:

image

Und wenn man noch tiefer runter geht, d.h. in das System hineinzoomt, dann kommen noch mehr Details in den Blick:

image

So kann es beliebig tief gehen. Software kann also als Baum dargestellt werden:

image

Das sieht nun wieder wie eine REOO Objekthierarchie aus. Das macht auch nichts, solange klar ist, dass der “Verfeinerungsbaum” einem wesentlichen Prinzip folgt: alle Aktionen, die nicht Blatt sind, haben ausschließlich die Aufgabe, Aktionen zu “Kooperativen” zu kombinieren.

In Nicht-Blättern stecken keine Algorithmen. Sie entscheiden nichts, sie enthalten keine Schleifen. Sie sorgen nur dafür, dass Output der einen Aktion zu Input für eine andere wird. That´s it.

Ebenfalls betonenswert: Funktionseinheiten auf allen Ebenen sehen gleich aus. Sie verarbeiten Input zu Output mit eventuellen Seiteneffekten. Und sie sind gleichzeitig Teil von darüber gelagerten Funktionseinheiten, von denen sie in einen Kooperationszusammenhang gestellt werden, wie sie Ganzes sind in Bezug auf Funktionseinheiten, die sie selbst zu einem Kooperationszusammenhang zusammenstellen.

Software ist damit grundsätzlich selbstähnlich aufgebaut; man könnte vielleicht sogar sagen, fraktal. Software ist eine Holarchie und die Funktionseinheiten sind ihre Holons.

Darüber habe ich früher schon öfter geschrieben wie hier oder hier oder 2005 hier. Aber auch wenn ich riskiere, damit zu langweilen, ist mir diese Sichtweise so wichtig, dass ich sie wiederhole. Wir tun uns einen Gefallen, wenn wir dahin kommen, Software so zu sehen. Aller Softwareentwurf kann durch solche Regelmäßigkeit nur einfacher werden.

Normalisierung

Zum Abschluss für heute noch eine Verallgemeinerung. Aktionen habe ich als Funktionseinheiten mit beliebig vielen Input- und Output-Strömen beschrieben. So soll es auch sein.

Für etwas mehr Regelmäßigkeit können Sie jedoch reduziert werden. Das hat später Vorteile, wie Sie sehen werden, wenn es an die Implementierung geht.

Die “Einheitsdarstellung” oder normalisierte Form für Aktionen ist diese:

image

Normalisierte Funktionseinheiten haben genau 1 Input-Strom und genau 1 Output-Strom. Immer.

Statt Input/Output entlang verschiedener Ströme fließen zu lassen, gibt es je nur einen Strom, auf dem Input/Output-Daten mit einem Qualifier näher beschrieben sind; der ordnet sie logisch einem der vielen früheren physischen Ströme zu.

Wie und ob sie sich von Input triggern lassen, sei dahingestellt. Ob sie Output herstellen, sei dahingestellt. Mir geht es um ihre Form. Alle Funktionseinheiten aller Ebenen können ohne Verlust an Flexibilität und Individualität gleich aussehen.

Zwischenstand

Soweit mein Traum von einer universellen, skalierbaren Grundstruktur von Software. Sie besteht aus einer beliebig tiefen Hierarchie von potenziell zustandsbehafteten und potenziell nebenläufigen Aktionen. Software tut etwas. Sie verarbeitet Daten. Deshalb wird sie beschrieben durch Tätigkeiten einheitlicher Form.

Klar, das ist Flow-Design nochmal beschrieben. Mir scheint eine so knappe Darstellung allerdings sinnvoll als Grundlage für das, was ich im Folgenden beschreiben möchte. Sie fasst den Stand der Flow-Design Überlegungen zusammen – allemal für die, die nicht alles verfolgen, was bisher dazu geschrieben wurde.

Ganz ohne Neuigkeit ist dieser Artikel andererseits aber auch nicht. Die Nebenläufigkeit ist jetzt “offiziell” im Bild und die Normalisierung. Der nächste Artikel wird zeigen, dass sie nicht nur konzeptionell nett ist.

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

Montag, 3. Oktober 2011

Digitale Erleichterung für den Schulalltag – oder: Kinder sind keine Scherpas

Wie wäre das, wenn Sie jeden Tag mit 25% Ihres Körpergewichts auf dem Rücken zur Arbeit gehen müssten? Für mich wären das ca. 17 kg, aber ich bin nicht groß. Für viele unter Ihnen wären das bestimmt 20 kg oder gar 25 kg. Ein Gewicht, dass Sie natürlich in einem Rucksack tragen können - nur wäre das jenseits dessen, was sie als bequem ansehen würden. Auf einen Sonntagswanderausflug würden Sie bestimmt höchstens 5 oder max. 7 kg mitnehmen, also deutlich weniger als 10% Ihres Körpergewichts.

Millionen Menschen in Deutschland können sich das allerdings nicht aussuchen. Sie sind gezwungen, um die 25% Ihres Körpergewichts jeden Tag zur Arbeit zu schleppen. Und es sind kleine Menschen, deren Haltungsapparat noch nicht voll ausgebildet ist. Es sind unsere Kinder.

Kinderarbeit in fernen Ländern beklagen wir zurecht. Dass Kinder in Deutschland jedoch täglich mit echten Lasten größere Strecken zurücklegen müssen, ist nicht auf unserem Radar.

Im Bild meine Tochter Verena. Sie ist derzeit 11 Jahre alt und besucht die 6. Klasse eines Gymnasiums in Hamburg. Ihr Ranzen wiegt um die 7,5 kg; ihr Gewicht ist 28 kg. Der Effekt ist deutlich zu sehen: kompensierende Haltung, ja, Fehlhaltung.

image

Klar, das Gewicht am langen Arm zu tragen, wäre noch schlimmer. Die Empfehlung "Ranzen statt Aktentasche" ist korrekt. Nur sollte das nicht bedeuten, dass jedes Ranzengewicht dann auch gleich akzeptabel ist. Ich finde 7,5 kg oder 25% des Eigengewichts jedenfalls deutlich zuviel.

imageIch weiß nicht mehr, wie schwer mein Schulranzen früher war. In der Grundschule war er jedenfalls deutlich kleiner, er sah eher so aus wie nebenstehen. Dass er mit 7,5 kg bestückt war, ist unwahrscheinlich.

Später im Gymnasium bin ich mit einem recht dünnen Samsonite Koffer ausgekommen. Den habe ich – gegen alle Empfehlung – am langen Arm getragen. Da waren bestimmt auch keine 7,5 kg drin.

Heute ist das anscheinend anders. Brotdose, Trinkflasche und Hefte gibt es immer noch. Die Zahl der zu schleppenden Bücher scheint sich aber erhöht zu haben. Hier das, was ich an einem Tag in Verenas Ranzen gefunden habe: Mathe, Englisch, Französisch, Geschichte, Erdkunde, Musik.

image

Manche Bücher können in der Schule gelassen werden, wenn sie nicht für Hausaufgaben benötigt werden. Gute Idee – die natürlich mindestens gelegentlich dazu führt, dass ein Kind ein nötiges Buch vergisst. Und wenn es Bücher zuhause hat, dann vergisst es sicher auch mal eines einzupacken, das am nächsten Tag gebraucht wird. Aber das ist alles nicht so schlimm wie das täglich hohe Gewicht.

7,5 kg kommen vor allem zusammen durch Schulbücher und Notizbücher, die die Lehrer fordern. Nicht Schreibhefte, sondern echte kleine “Schreibbücher” (z.B. für spezielle Ansagen der Klassenlehrer).

Zum Gewicht kommt die Qualität der Bücher. Was trägt denn meine Tochter da. In Hamburg herrscht derzeit Lehrmittelfreiheit, d.h. Schulbücher müssen nicht gekauft werden (oder zumindest nicht alle). D.h. die Kinder “erben” ihre Bücher von Vorgängern. So sehen sie denn auch aus. Hier als Beispiel das Musikbuch:

image image image

So viel ist uns also die Bildung unserer Kinder wert?

Aber ich will nicht in ein Lamento über unser Bildungssystem verfallen. Mir geht es hier um etwas anderes. Ich finde die Gewichtsbelastung und auch die schlechte Lehrmittelqualität nämlich gänzlich unnötig. Sie ist anachronistisch, weil es besser geht. Es geht ganz einfach viel besser. Nämlich so:

image image

Das ist das iPad von Verena. Auf ihm sind alle Schulbücher, die sie sonst im Ranzen trägt, als PDFs. Das iPad 1 wiegt damit 0,875 kg!

Das iPad mit allen Büchern der 6. Klasse wiegt nur knapp 10% des Ranzens und also nur knapp 2,5% von Verena. Das, so finde ich, ist ein angemessenes Gewicht für den täglichen Schulweg.

Zugegeben, im iPad ist noch keine Brotdose und keine Trinkflasche enthalten :-) Aber alle Schulbücher und alle Schreibhefte können darin sein. Ohne Gewichtsveränderung kann darin sogar jedes Buch jeder Jahrgangsstufe inkl. aller je gemachten schriftlichen Ausfertigungen gespeichert sein. Rein technisch könnte Verena also mit einem iPad zur Einschulung ausgestattet werden und es bis zum Schulabschluss behalten. In 12 (oder 13) Jahren müsste sie für den Unterricht nicht ein Buch schleppen und nicht ein Heft kaufen. Sie könnte alle Arbeiten mit und im iPad erledigt.

Technisch ist das kein Problem.

Ob das immer didaktisch/pädagogisch wünschenswert ist, ist eine andere Frage. Mit einem Stift das Schreiben auf Papier zu lernen, ist sicher eine Fertigkeit, die Schule auch vermitteln sollte. Allerdings geschieht das heute schon schlecht genug, wie das Gekrakel vieler Schüler beweist. Der Zeigefinger sollte also nicht zu doll wackeln, wenn es ums Schreiben auf einem iPad geht. (Ob mit der virtuellen Tastatur oder einer zusätzlichen geschrieben würde, sei auch nochmal dahingestellt.)

Was in der Schule gelesen wird, was für die Schule geschrieben wird, was für die Schule “collagiert” wird (Hausarbeiten aus Text und Bildern), was notiert wird… das kann genauso gut oder gar noch besser (leichter, in höherer Qualität, mit mehr Lerneffekt fürs restliche Leben) mit einem iPad getan werden.

imageDamit kann es heute losgehen. Schulbücher müssten nicht mal aufwändig umgestaltet werden; ein Scan wie ich es mit den Büchern von Verena gemacht habe, reicht erstmal. Als Leseprogramm finde ich den GoodReader sehr nützlich.

Ein kleines Problem machen “Workbooks”, also Bücher, in die etwas hineingeschrieben werden soll. Die könnten technisch aber als PDF-Formulare ausgelegt werden. Das ist etwas mehr Aufwand als ein reiner Scan – doch der ist sehr überschaubar, wenn der ein Verlag das einmal tun würde zum Nutzen aller Schüler.

Schulhefte und Notizbücher werden ersetzt durch diverse Apps. An Textverarbeitungen und Notiz-Apps gibt es keinen Mangel. Da kann man organisieren und reinmalen und schreiben, dass es eine Freude ist. Und wenn die Lehrerin Termine ansagt, können die sogar in Kalender eingetragen werden. Ja, die Lehrerin könnte sogar einen Kalender für die Klasse zentral führen. Dann müssten nicht 30 Kinder eine Notiz machen. Den Kalender könnten Eltern dann abonnieren.

Es ist überhaupt nicht auszudenken, wie der Schulalltag sich vereinfachen ließe, wenn denn die Kinder statt mit gewichtigen Papierbergen mit einem iPad (bzw. einem vergleichbaren Device) ausgestattet würden. Ich wage ja gar nicht auszumalen, was da alles möglich wäre in puncto Apps für die Bildung. “Spielend lernen” könnte eine ganz neue Bedeutung bekommen. Physikalische Experimente auf dem iPad, Exploration mathematischer Probleme, ein anderer Zugang zur Chemie, Recherchieren am PC nicht als mühseliger Sonderfall, sondern als Bestandteil des Schulalltags…

Aber ich höre sie schon, die Kritikusse: Dem Plagiat sei damit ja Tür und Tor geöffnet. Und die wichtigen Fertigkeiten im Umgang mit dem Papier, die dann nicht mehr gelernt würden. Sowieso sei damit die Verblödung der Kinder und Jugendlichen durch “den Computer” auch noch staatlich gefördert.

imageKinder die zerfledderte Bücher schleppen und in Hefte krakeln: das ist der Inbegriff heutigen Schulideals, scheint mir. Naja, kein Wunder, wenn ich Lehrer sehe, die nicht einmal ein Handy haben und sich von der Elternschaft auch keines für den gelegentlichen Gebrauch zur Abstimmung bei Klassenreisen schenken lassen. Da wird kokettiert mit der eigenen Unkenntnis, wie Fotos elektronisch verbreitet werden könnten. (“Das geht doch irgendwie mit einer CD oder so, nicht wahr? Ich kenne mich da nicht aus. [hihi]”)

Nein, ich halte weiterhin dagegen: Eine Schulwelt, in der jedes Kind mit einem iPad (bzw. ähnlichem Device) ausgestattet ist, halte ich für wünschenswert.

Handfest dagegen sprechen nicht eventuelle pädagogische Einwände einer zaghaften Lehrerschaft, die sich früher schon gegen Schiefertafeln gewandt hat, als man noch auf Birkenrinde in der Schule geschrieben hat.

Handfeste Einwäde sind für mich derzeit:

  • Ein iPad kostet eine ganze Menge. Das kann sich nicht jede Familie für jedes Kind leisten. Es gibt auch günstigere Varianten, aber das kapazitive Display und die Geschwindigkeit sind für mich erstmal Minimalanforderung. Schlechter sollten Schul-Devices nicht ausgestattet sein.
    imageIch bin allerdings sicher, dass die Zeit hier für die Schüler arbeitet. In Russland ist man augenscheinlich schon weit(sichtig)er.
    Auf der anderen Seite: Wenn ein Device für mehrere Jahre gekauft wird, sagen wir mal mindestens für die Zeit nach der Grundschule (also max. 8-9 Jahre), dann wären selbst Kosten von 500 EUR kein Problem. Pro Jahr wären vielleicht 75 EUR fällig (inkl. einer Verlustversicherung). Dafür ließe sich doch eine Finanzierungsform finden, oder? Ein bisschen Kreativität wäre halt gefragt.
    Letztlich müsste sich am Preis also gar nicht soviel ändern. Mit einem potenten Hardware-Sponsor und einem potenten Telco-Provider und einer potenten Versicherung wäre da was zu machen. Warum probiert eine Privatschule das nicht einfach einmal aus? Fragen köst nix.
  • Wenn ein iPad verloren ginge, gestohlen oder beschädigt würde im Schulalltag, dann wären gleich alle Aufzeichnungen und Bücher weg. Dass das einem Ranzen passiert, ist möglich, aber unwahrscheinlich. Ein iPad hingegen ist empfindlicher und attraktiver für Diebe.
    Es müssten Vorkehrungen verschiedener Art getroffen werden, um einem Verlust entgegen zu wirken und ihn im Notfall zu kompensieren. Daten können über die Cloud gesichert werden. Der Zugang kann personalisiert werden. Klassenräume könnten abgeschlossen werden in der Pause. Und Devices könnten versichert werden. Man sollte eh darüber nachdenken, ob die Devices nicht “im Abo” gekauft werden, so dass sie nach vielleicht 3 Jahren ohnehin ausgetauscht würden.
  • imageSchulbücher müssten digitalisiert werden. Das kann jeder für sich machen, wie ich es getan habe. Aber eigentlich ist das natürlich Aufgabe der Verlage. Die tragen natürlich starke Bedenken, was ihre Umsätze angeht. Doch das wäre eigentlich kein Problem. Schulen kaufen heute Buchkontingente, das können sie auch morgen tun.
    Wie gesagt, im ersten Schritt müssten die Bücher nicht mal aufgepeppt werden. Ein Scan reicht in den meisten Fällen aus.
    Und danach kann jeder Verlag schrittweise seine Bücher in Apps oder anderes umwandeln (die die Kinder (bzw. ihre Eltern) kaufen). Da würde sich sogar ein Markt für weitere Titel auftun: das Schulbuch muss gekauft werden, doch zum Schulbuch gibt es dann vom Verlag noch Nachhilfe-Apps. Ha! Was für ein Geschäft!
  • Verena könnte heute womöglich schon ihr iPad in die Schule mitnehmen. Da ist ja alles, was sie braucht, drauf. Die Lehrer würden die Stirn runzeln, zucken, doch am Ende es akzeptieren, denke ich. Gefragt habe ich allerdings nicht, weil Verena nicht will. Es wäre ihr unangenehm, als einzige mit einem solchen Device im Unterricht zu sitzen. Da schleppt sie lieber 7,5 kg, als sich so als Außenseiter zu zeigen.
    Das bedeutet, Devices müssen in einer Weise eingeführt werden, die “peerkompatibel” ist. Kindern dürfen sich dadurch nicht ausgegrenzt fühlen. Es ginge also nur klassenweise.

Soweit die Hürden, die ich sehe. Es sind keine didaktischen, keine pädagogischen, sondern eher organisatorische.

Keine scheint mir aber unüberwindlich. Im Gegenteil. Wenn auch nur eine Schule das Ergebnis für wünschenswert hielte, könnte sie aus dem Stand ein Experiment aufsetzen. Warum nicht eine Klasse in einem höheren Jahrgang (z.B. 10. Klasse) mit Devices ausstatten und schauen, was passiert?

Sponsoren für Hardware, 3G und Versicherung ließen sich ganz bestimmt finden. Die Kosten wären dann kein Problem.Schulverlage würden es sicher auch mitmachen.

Die größte Herausforderung wäre wahrscheinlich, die Lehrerschaft zu überzeugen. Die kann selbst nicht verlässlich mit Devices umgehen. Die kann schon gar nicht verlässlich verstehen, was ihre Schüler mit Devices heute schon daheim alles tun. Die Barriere ist mithin in den Köpfen.

Deshalb scheint mir eine Privatschule der vielversprechendste Keim für eine solche Entwicklung. Dort ist man mehr als anderswo darauf angewiesen, sich zu entwickeln.

Also: Wo ist die innovative Schule, die unsere Kinder erleichtert? 0,875 kg sind machbar. Kein Kind muss 25% seines Körpergewichts an Material zur Schule schleppen.

Wenn uns unsere Kinder wirklich wichtig sind, dann bemühen wir uns, sie mit dem Besten auszustatten, was unsere Gesellschaft hervorgebracht hat. Und das sind nicht nur Goethe, Einstein, klimatisierte Busse für Klassenreisen und hübsche Tafelbilder. Machbar ist viel mehr. Machbar ist auch mehr als Smartboard-Schulen heute tun. Wir müssen es nur wollen.

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

Samstag, 1. Oktober 2011

Ungesunde Zahlungshemmung

imageZahlen für Fortbildung? Gerade habe ich eine Folge von Uncle Bobs Videos gekauft. Dabei habe ich ein Zucken gespürt. "12 USD für ein Video? Lohnt sich das?" Trotz meiner Zweifel habe ich gezahlt...

...und als bei Paypal dann stand "8,96 EUR", habe ich gedacht: "Wie blöd bin ich eigentlich? Ich denke darüber nach, 8,96 EUR für meine Fortbildung auszugeben - aber ich zucke nicht, wenn ich für den selben Preis einen Roman kaufe oder ins Kino gehe. Das ist unverhältnismäßig."

Ja, genau, das ist unverhältnismäßig. Mein Zucken war Symptom eines verqueren Wertesystems: Entertainment darf Geld kosten, Weiterbildung darf kein Geld kosten.

Das, was in Zukunft Geld bringt (weil es meine Kompetenz erhält oder vergrößert), darf kein Geld kosten - das, was mich Entspannt (auch wichtig, klar), also kein Geld bringt, darf Geld kosten?

Natürlich ist das Missverhältnis nicht so krass. Es geht nicht um Geld ausgeben dort und gar kein Geld ausgeben hier. Ich gebe selbstverständlich auch sonst Geld aus für Weiterbildung (insb. in Form von Büchern) und manches Entertainment ist mir zu teuer.

Mein Gefühl ist jedoch, dass das Zucken auf ein grundsätzliches und nicht nur bei mir Vorhandenes Missverhältnis hinweist. Wir haben durch das Internet als bodenlosem Becher der kostenlosen Information schleichend eine ungesunde Attitüde entwickelt. Ja, ungesund ist sie, so glaube ich, weil sie letztlich unsere ökonomische Gesundheit untergräbt.

Die Sache mit dem Geld ist im real existierenden Wirtschaftssystem essenziell. Wir brauchen es für alles mögliche. Deshalb sind wir darauf angewiesen, dass wir Geld verdienen. (Das mag man unschön finden, ist aber erstmal so.) Also verlangen wir für unsere eigene Arbeit gutes Geld. Wir finden, wir verdienen den Preis, den wir aufrufen (in Form von Stundensatz oder Gehalt).

Wir wollen also viel Geld bekommen - anderen wollen wir aber möglichst wenig Geld geben. Wir wollen die Leistung von Uncle Bob möglichst umsonst (zumindest war ich einen Moment enttäuscht darüber, dass seine Videos nicht umsonst wie sein Blog sind (oder nicht viel weniger kosten)), wir wollen die Leistung von MSDN online kostenlos, wir wollen die Leistungen der vielen Blogger kostenlos, wir wollen ein kostenloses Stackoverflow, wir wollen ein kostenloses Coderepository online usw. usf.

Wir sind maßlos in dem, was wir alles kostenlos haben wollen.
Gleichermaßen sind wir aber maßlos in dem Geld, was wir eigentlich für unsere eigene brilliante Leistung bekommen wollen.

Das ist doch eine Asymmetrie, ein Missverhältnis, das nicht funktionieren kann. Das kann nur zu Spannungen führen. Alles bekommen, aber nichts zahlen? So "denken" 3jährige. Als Erwachsene sollten wir es besser wissen.

Die Preisspirale zu unserem Nutzen umkehren

Wir müssen uns einfach immer wieder klar machen: Wenn wir selbst so denken, dann denken auch unsere Kunden so. Die fragen sich auch, warum sie uns eigentlich Geld geben sollten. Warum sollten sie für unsere Software etwas bezahlen, wenn es doch woanders Open Source kostenlos gibt?

Wie fühlt sich das für Sie an? Ihr Kunde mag es Ihnen (bzw. dem Vertrieb Ihres Unternehmens) nicht sagen, aber denken wird er es: “Boah, soviel Geld… warum soll ich das ausgeben? Im Internet gibt es soviel Software kostenlos.”

Ist das ein gutes Gefühl, wenn Sie sich überlegen, wie Ihre Kunden über Sie denken? Unabhängig davon und erstmal wichtiger: Wohin führt denn eine solche Haltung? Sie setzt eine Abwärtsspirale in Gang. Und die dreht sich ja auch schon. Uns wird schon schwindelig davon, wenn wir auf weithin sinkende Löhne und Stundensätze blicken.

Dann reagieren wir reflexartig: Kosten senken! Am besten selbst alles billiger fordern. Warum kostet Uncle Bobs Video eigentlich soviel wie ein normaler Kinobesuch? Kann der das nicht billiger machen für mich als armen gebeutelten Entwickler, der unter Kostendruck steht und dem die Kunden nicht mehr soviel Zahlen wollen?

Merken Sie es? Alles dreht sich. Nach unten. Weil Sie und ich so “kleinlich denken”. Wir glauben, wir könnten (langfristig) einen Blumentopf gewinnen, indem wir immer billiger einkaufen – aber an unseren eigenen Umsatzforderungen nichts ändern.

Das ist Quatsch.

Entweder sind wir konsequent und senken auch unsere Forderungen.

Oder wir sind konsequent und erhöhen unsere Ausgabenbereitschaft.

Der Vergleich des Preises von Uncle Bobs Video mit einer Kinokarte hat mir (mal wieder) gezeigt, wie meine Entscheidung ausfallen sollte: Ich erhöhe meine Ausgabenbereitschaft. Das ist mein klitzekleiner Beitrag zur Umkehr der Spiralbewegung. Denn wenn ich bereit bin, Geld auszugeben – insbesondere für etwas, das mir ja hilft, meinen Wert zu halten/steigern –, werden vielleicht auch andere Menschen so denken. Das kommt dann auch mir zugute.

Wertschätzung

Der rohe Geldfluss ist aber nur eine Hälfte des Problem bei diesem Missverhältnis. Geld ist nicht alles. Wir wollen auch für unsere Arbeit geschätzt werden. Wir sind ja (hoffentlich) stolz auf das, was wir leisten. Allemal die Software Craftsmen sollten sich diesem Gefühl verbunden sehen.

Wie drücken wir denn aber anderen unsere Wertschätzung aus? “Gut gemacht!” mag ja im Kollegenkreis probat sein, doch in anonymen Beziehungen ist es schwieriger. Klar, der positive Kommentar eines Leser zu einem Blogbeitrag von mir freut mich. Und weitere positive Kommentare freuen mich noch mehr.

Positive Kommentare skalieren jedoch nur schlecht. Und irgendwann, ja, das gebe ich zu, irgendwann sind sie mir auch nicht mehr genug. Denn von positiven Kommentaren kann ich meine Miete nicht bezahlen. Niemand lebt von Luft und Liebe und Schulterklopfen. So ist das halt grad noch in unserer Welt. Deshalb haben wir gelernt, Wertschätzung in Geld auszudrücken und Geld als Wertschätzung zu akzeptieren. (Und wer das nicht glaubt, der verzichte einfach auf die nächste Gehaltserhöhung.)

Dass nicht-monetäre Wertschätzung ihre Grenzen hat, zeigt sich für mich auch im real existiert habenden Sozialismus. Dort wurden Orden als Wertschätzung verteilt. Helden der Arbeit wurden gekürt. Aber hat das zufrieden gemacht? Offensichtlich nicht dauerhaft.

Wertschätzung in einer Form, die den Empfangenden in die Lage versetzt, sie auch noch in die Erfüllung anderer Bedürfnisse zu konvertieren, ist doppelt gegebene Wertschätzung.

Geld ist nicht alles. Geschenke zu Weihnachten sollten nicht Bedeutung allein durch ihren Preis bekommen. Das ist selbstverständlich. Nur geht es mir grad nicht um Weihnachten, sondern eine essenziell ökonomische Situation: die Nutzung von mit Mühe hergestellten Produkten, seien das Entwicklervideos oder Code-Repositories.

Wenn wir für diese Produkte Geld bezahlen, dann tragen wir nicht nur zu ihrem Erhalt bei (s.o.), sondern drücken damit auch noch Wertschätzung aus. Das sollten wir nicht abtun.

Wir möchten wertgeschätzt werden? Dann sollten wir bewusster selbst wertschätzen. Das kann in Form von positiven Äußerungen sein – am Ende skaliert Geld aber besser. Uncle Bob könnte die vielen wertschätzenden persönlichen Kommentare gar nicht wertschätzen. Aber wenn er auf seine Paypal-Abrechnung schaut, fühlt er sich bestimmt wertgeschätzt. Das mag dann abstrakter sein, aber es kommt an. Ja, ich glaube, dass Uncle Bob meine 12 USD Wertschätzung wahrnimmt. Nicht persönlich, aber doch.

Wertschätzung dreht sich auch in einer Spirale. Sie wird allseits größer, wenn wir bereit sind, wertzuschätzen. Sie wird kleiner, wenn wir damit zurückhaltend sind. Was wollen wir?

Beim Geld wie bei der Wertschätzung ist es so, dass wir (mittel- bis langfristig) nicht damit rechnen können, etwas zu bekommen, was wir nicht bereit sind zu geben.

Das Zucken anlässlich Uncle Bobs Video hat mich aufgerüttelt. Ich werde mich bemühen, in Zukunft bewusster erstmal zu Geben.

Dienstag, 13. September 2011

Spinning – Vorschlag für den Kern jedes Vorgehensmodells

Über eine Iterationslänge von 1 Tag habe ich ja schon öfter geschrieben. Dazu stehe ich weiterhin. Allerdings ist mir aufgefallen, dass sie nicht an erster Stelle stehen sollte. Deshalb versuche ich mal eine andere Formulierung:

Im Kern von Scrum steht der Sprint von mehreren Wochen, d.h. ein fixes Auslieferungsdatum mit fixem Scope. Scrum ist damit fundamental zeitorientiert. Pro Sprint werden mehrere "Arbeitspakete" angegangen, die alle zum selben Zeitpunkt abgeliefert werden müssen.

Im Kern von Kanban steht die Warteschlange. Kanban ist damit fundamental flussorientiert. Wie lange die Ablieferung eines "Arbeitspaketes" dauert, ist egal, solange dadurch keine Verschwendung entsteht (Halden von auf Vorrat produziertem "Zeug").
Klingt irgendwie alles sinnig, oder?

Wenn wir uns das aber mal auf der Zunge zergehen lassen, dann sollte uns "im Abgang" ein bitterer Geschmack auffallen. Es fehlt nämlich etwas. Und was fehlt, ist oft schwer zu erkennen.

Es fehlt der Kundennutzen, es fehlt die Qualität. Beides steht weder bei Scrum noch bei Kanban an erster Stelle. Und nur das meine ich natürlich: Er steht nicht an erster Stelle. Er ist nicht offensichtlich.

Ich will also nicht sagen, dass Scrum und Kanban nicht an Kundennutzen oder Qualität interessiert seien. Nein, im Gegenteil. Teams, die Scrum oder Kanban oder Scrumban machen, wollen selbstverständlich Qualität herstellen. Niemandem soll der Wille zu Qualität abgesprochen werden.

Allerdings glaube ich, dass ein Qualitätsziel schwieriger als nötig (oder wünschenswert) erreicht wird, wenn es nicht an erster Stelle steht. Außerdem haben wir es sowieso schwer, ein Qualitätsziel zu erreichen; wie messen wir Qualität? Und je größer der Brocken, der in Qualität hergestellt werden soll, desto schwieriger.

Viel leichter ist es, einem Prozess zu folgen. "Haben wir X getan, so wie es der Prozess vorschreibt?" Diese Frage ist ungleich einfacher zu beantworten.

Je weiter oben auf der Prioritätenliste eines Vorgehens dann eine Handlung steht, desto eher wird sie auch ausgeführt. "Haben wir den Sprint eingehalten?", "Ist die Warteschlange übergelaufen?" - das sind die beiden ersten Fragen, die sich Scrum- bzw. Kanban-Teams stellen. In beiden kommt Qualität nicht vor.

Wie kann nun ein Vorgehen aussehen, dass Qualität an die erste Stelle setzt? Die Handlung mit höchster Priorität muss mit Qualität zu tun haben. Weitere Handlungen/Aspekte können sich dann auf Zeit oder Fluss oder sonst etwas beziehen. So wie sich weitere Handlungen/Aspekte bei Scrum und Kanban auf Qualität beziehen.

Mein Vorschlag:

1. Füge der Software den kleinsten vertretbaren Nutzen auf dem vereinbarten Qualitätsniveau hinzu.

Das sollte die zentrale, die erste Aufforderung eines Vorgehensmodells für Software sein.

Nutzen: Irgendetwas, das für den Kunden einen Wert darstellt, das ihm etwas bringt, das er beurteilen kann, um festzustellen, ob die Entwicklung auf dem richtigen Weg ist. Nutzen kann in Funktionalität bestehen oder der Erfüllung einer äußeren nicht-funktionalen Anforderungen.
Hinzufügen: Die Software soll etwas mehr Nutzen irgendeiner Art erhalten. Der Nutzenzuwachs kann in etwas mehr Funktionalität bestehen oder in etwas höherer Geschwindigkeit oder in etwas besserer Usability usw.

Kleinstmöglich: Es geht nicht darum, eine ganze User Story oder auch nur ein ganzes Feature hinzuzufügen. Nein, es geht um viel kleinere Inkremente, aus heutiger Sicht quasi unvorstellbar und schmerzhaft kleine Inkremente. Phantasie ist gefragt, Anforderungen so hauchdünn zu schneiden.

Damit meine ich natürlich nicht beliebig klein. Wie immer im Leben ist auch hier eine Balance zu finden zwischen Nutzenzuwachs und "administrativem Aufwand". Da aber alle andere Vorgehensmodelle auch nicht ohne Balance und Fingerspitzengefühl auskommen, finde ich es nicht schlimm, wenn es hier auch nötig ist.

Warum so kleine Inkremente? Ich würde ja sogar formulieren, sinnvoll kleinstmögliche Inkremente. Aber dann kommt jemand und sagt, so hauchdünne Scheiben machen ja eben für den Kunden keinen Sinn.

Darum geht es ja aber auch nicht. Selbst die in einem Scrum Sprint realisierten User Stories machen für den Kunden keinen Sinn in dem Sinne, als dass er nach dem ersten Sprint die Software produktiv einsetzen würde. Dazu sind schon ein paar mehr Sprints nötig in den meisten Fällen.

Wirklich sinnvoll ist für den Kunden nur, was ihn im Tagesgeschäft einen guten Schritt voran bringt. Am besten natürlich die Erfüllung der kompletten Anforderungen. Das ist ja aber bei keinem Vorgehensmodell möglich. Scrum liefert das nicht nach einem Sprint und Kanban nicht, wenn am Ende der Produktionskette das erste mal etwas heraustropft.

Der kleinstmögliche Nutzenzuwachs dient also nicht irgendeinem Sprung nach vorn im sofortigen produktiven Einsatz, sondern in einem _beurteilbaren_ Zuwachs. Ein Team kann viel Code in 14 Tagen schreiben - aber ob damit die Software näher an die Wunscherfüllung des Kunden kommt, kann der nicht beurteilen. Agiles Vorgehen stellt mithin den Nutzen in den Vordergrund; es wird in Durchstichen entwickelt. So auch hier.

Nutzen ist alles, dessen Qualität (d.h. Anforderungskonformität) der Kunde beurteilen kann. Nutzen hat also nicht zwingen mit GUI oder Datenbank oder Verteilung zu tun. Deshalb kann Nutzen auch in viel dünneren Scheiben und viel schneller produziert werden, als gemeinhin angenommen.

Und warum nun diesen Schritt als ersten im Vorgehensmodell? Weil er erstens auf äußere und auch innere Qualität fokussiert und zweitens schnelles Feedback ermöglicht und drittens auch noch der Grundbaustein konstanten Flusses ist. “Kleinstmöglicher Nutzen” entspricht der Forderung nach “small batch sizes”.

Qualität und Feedback vor allen anderen Gesichtspunkten. Das ist mir wichtig. Andere kommen erst danach, z.B.

2. Schritt 1 sollte am Ende des Tages abgeschlossen sein.

3. Zurück zu Schritt 1. Es können auch mehrere Nutzeninkremente (nacheinander) gem. Schritt 1 hergestellt werden, solange die Bedingung von 2 erfüllt ist

Ziel ist ein konstanter Fluss von Nutzenzuwächsen. Durch diese Vorhersehbarkeit und Verlässlichkeit entsteht Vertrauen in die sonst so schwer für Außenstehende greifbare Softwareentwicklung.

Das war´s. Das ist für mich der Kern des Vorgehens in der Softwareentwicklung. Und weil sich die dabei so schnell dreht, nenne ich das mal Spinning.

Wer jetzt Zeit oder Fluss weiter ins Spiel bringen möchte, der fühle sich eingeladen:
Kanban passt wunderbar zu Spinning. Nutzenzuwächse sollten nicht auf Halde geplant werden. WIP sollte limitiert werden; am besten arbeitet das Team zur Zeit immer nur an einem Nutzenzuwachs. Wenn die Herstellung des Nutzenzuwachses aus mehreren Schritten besteht, dann sollten die über Warteschlangen entkoppelt werden.

Scrum passt auch zu Spinning. Wenn wirklich, wirklich nötig, können die Nutzenzuwächse mehrerer Tage zusammengefasst dem Kunden zur Beurteilung vorgelegt werden. Der PO kann sie sich am Ende des Sprints anschauen, wenn er mag. Damit würde zwar die Chance der hohen Umdrehungszahl nicht ausgereizt, aber es wäre halt möglich. Ein Team kann Spinning einführen, auch wenn der Kunde noch nicht genauso schnell ist. (Allerdings sollte er dahin gebracht werden.)


Spinning ist also orthogonal zu anderen Vorgehensmodellen. Es kann unabhängig davon eingeführt werden, sogar im Wasserfall. Die Vorteile:
  • Voranschreiten der Codeproduktion im Sinne der Agilität durch höchste Priorität für Nutzenherstellung
  • Fokus auf Qualität durch höchste Priorität für äußere Qualität (Nutzen gem. Anforderungen) und innere Qualität (täglicher Druck auf Evolvierbarkeit durch Nutzenproduktion)
  • Chance für kürzesten Feedbackzyklus (Iterationsdauer max. 1 Tag)
  • Motivation/Zufriedenheit durch “abgeschlossenes Tagwerk”

Wann schicken Sie Ihr Projekt ins Sportstudio? :-) Mit dem Spinning können Sie sofort beginnen.

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

Dienstag, 6. September 2011

Softwareevolution in Vielfalt

In einem früheren Posting habe ich über Rahmenbedingungen für die Evolution von Software nachgedacht. Den dort genannten möchte ich nun noch eine hinzufügen: die Vielfalt.

Ich glaube, dass Evolution eines Ganzen schwieriger ist, als die Evolution von Vielem, das eine Summe hat.

Das Leben auf der Erde ist nicht ein Organismus (auch wenn es die Gaia-Hypothese gibt), sondern es besteht aus unzähligen. Und es evolviert in jedem einzelnen.

Genauso ist ein Betriebssystem wie Unix oder Windows nicht “ein Ding”, sondern besteht aus Hunderten oder gar Tausenden kleinen “Dingen”, die erst in Summe das ergeben, was wir mit dem Namen “Unix” oder “Windows” betiteln.

Mein iPhone ist einerseits ein “Ding”, eine Hard-/Softwareplattform. Andererseits ist es etwas, das sich entwickelt. Die Summe einer wachsenden Zahl von Teilen, den Apps. Mein iPhone evolviert sozusagen; es passt sich meinen Bedürfnissen ständig an. Das ist ganz einfach möglich, weil es nicht monolithisch ein “Ding” ist wie mein vorheriges Handy. Die Evolvierbarkeit steckt in der Möglichkeit zur Vielfalt.

Ich kann meine Schreib-Anforderungen iterativ immer besser erfüllen, weil ich meine Schreib-Apps getrennt von den Diagramm-Apps und die wiederum getrennt von den Musik-Apps “weiterentwickeln” kann. Ich kann mit “Notizen” beginnen, zu “Nebulous” weitergehen, auf “Pen & Paper” umsatteln und schließlich bei bei “Simplenote” enden.

Die Erfüllung anderer Anforderungen, ist von dieser Weiterentwicklung nicht betroffen. Ich kann auch jederzeit meinen Fokus wechseln. Mal möchte ich beim Schreiben vorankommen, mal möchte ich die Fotonachbearbeitung verbessern.

Diese Offenheit zur Evolution eines Ganzen durch feingranulare Evolution einer Vielfalt von Summanden, halte ich für eine Voraussetzung für evolutionären Erfolg. Unix hat es in Software vorgemacht, der PC hat es in Hardware nachgemacht, das Web hat dieses Prinzip ins Extreme getrieben, das iPhone setzt wieder darauf.

Voraussetzung für eine derartige Evolution der Vielfalt ist eine Plattform. Bei Unix war es der Kernel, würde ich sagen, beim PC der Bus mit seinen Slots für die Erweiterungskarten, beim Web TCP+DNS+HTTP+HTML, beim iPhone Hardware+iOS+AppStore.

Und was bedeutet das für Ihre Anwendung?

Wenn der Kunde kommt und sagt, er wolle “eine Anwendung”, dann nehmen Sie das “eine” nicht so genau. Ihr Kunde will einen Anforderungsberg abgetragen bekommen. Klar. Aber letztlich ist ihm egal, ob das mit 1 Anwendung (lies: EXE) geschieht, solange es praktikabel und nachhaltig geschieht.

Denken Sie also nicht reflexhaft an 1 großes Fenster für die GUI, in dem sich irgendwie alles abspielt. Denn das zwingt den Code in schnell in 1 großen Kasten, in dem er leicht verklebt.

Stattdessen überlegen Sie, wie Sie die Lösung als Summe einer Vielfalt von Apps beschreiben können. Ja, ich meine App in der Linie von iPhone oder iPad Apps. Das sind kleine, sehr fokussierte Programme. Sie dienen einem überschaubaren Zweck. Ihre Usability ist zu dessen Erfüllung maximiert.

Deshalb sehen die Apps auch alle sehr unterschiedlich aus. Eine Foto-App ist ganz anders als ein Spiel und das unterscheidet sich von der Mindmap-App. Das nehmen wir ihnen nicht übel, sondern begrüßen es. Auch, dass wir auf dem iPhone nur jeweils 1 App zur Zeit sehen, stört uns meist nicht. Im Gegenteil: so fokussieren wir uns.

Ich glaube, dass wir diesen Ansatz auf unsere “Geschäftsanwendungen” übertragen sollten. Wir sollten sie zerschlagen in eine Vielfalt von Apps. Und jede dieser Apps kann separat evolvieren.

Beispiel Faktura. Landläufig würde ein Softwarehaus für die Anforderungen, die hinter dem Begriff stehen, eine Anwendung bauen. Eine EXE, die auf allen Desktops im Büro installiert wird. (Und vielleicht noch ein SQL Server auf einem Server-Rechner.) Alle Funktionen würden über ein Hauptfenster erreicht und liefen im Faktura-Prozess ab.

Jede Änderung würde dann notwendig die eine Codebasis betreffen. Unschöne Kopplungen würden bei aller Mühe immer wieder entstehen. Die Evolvierbarkeit würde schnell sinken. (Ja, dagegen kann man sich mit Prinzipien und Praktiken stemmen, doch die grundlegend monolithische Sicht auf die Anforderungen macht es schwer für sie zu greifen.)

Wie anders würde die Entwicklung verlaufen können, wenn das Projekt mit evolvierender Vielfalt angegangen würde. Dann gäbe es eine App für die Rechnungslegung, eine App für die Stammdatenpflege, eine App für den Zahlungseingang, eine App für das Mahnwesen und eine App für den Chef. Vielleicht auch noch eine App für den Import und Export. Oder noch eine App für die Gestaltung unterschiedlicher Rechnungsvorlagen.

Es gäbe nicht mehr eine große Codebasis. Es gäbe ja nicht mehr eine Anwendung, sondern viele, ein Anwendungssystem. Die könnten Codeteile gemeinsam verwenden. Aber sie wären grundsätzlich sehr deutlich getrennt. Änderungen würden dann nicht mehr zu ungewollten Kopplungen in der Codebasis führen, da sie meist nur eine App zur Zeit beträfen. An manchen Apps würde mehr geschraubt als an anderen. Apps, die später in Angriff genommen würden, könnten intern anders aufgebaut sein, als frühere Apps, weil man schon aus Fehlern gelernt hat. Überhaupt müssten Entscheidungen nicht immer für “alles” getroffen werden; keine Notwendigkeit für 1 allumfassende Datenbank, 1 allumfassendes Datenmodell, 1 alle glücklich machende Persistenztechnologie, 1 GUI-Technologie usw.

Eine App könnte ihre Daten in SQL Server speichern, die andere in MongoDb. Die eine App könnte noch mit einer WinForms-Benutzerschnittstelle versehen sein, die andere WPF benutzen. Und wenn in einer App die Unwartbarkeit erreicht sein sollte, dann könnte die ganz unabhängig von allen anderen neu gemacht werden.

Ich kann nur Vorteile in einer solchen Vielfalt erkennen. Sie eröffnet Chancen, ohne einzugrenzen.

Es gibt lediglich eine Hürde: die in unseren Köpfen. Wir müssen Anwendungen so denken wollen. Technisch spricht nichts dagegen, sondern alles dafür. Auch sollten uns die genannten Präzedenzfälle ermutigen. Wir alle lieben Plattformen, die wir stückweise erweitern, die wir evolvieren können. Warum also nicht die Vorteile feingranularer Vielfalt für unsere eigenen Projekte nutzen?

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

PS: Einige Leser werden nun denken, ich würde damit vorschlagen, dass eine GUI-Shell oder ein Basisframework wichtig seien. Ohne etwas Gemeinsames unter allen Apps oder über allen Apps sei solche Vielfalt nicht zu machen. Nichts könnte mir jedoch ferner liegen. Anwendungsevolution durch eine Vielfalt an Apps hat keine Voraussetzung; nichts muss erstmal eingerichtet werden. Jede App kann unabhängig von anderen jederzeit begonnen werden. Das Betriebssystem als Plattform reicht.

PPS: Das Ganze nicht als Monolith zu sehen, sondern als Summe von vielen Teilen, sollte sich natürlich durch alle Ebenen einer Software ziehen. Die ganze Anwendung besteht aus unabhängig evolvierbaren Apps. Jede App besteht aus unabhängig evolvierbaren Bausteinen. Und diese Bausteine wiederum sind unabhängig evolvierbar. Apps sind mithin Ausdruck der Selbstähnlichkeit von Software.

Bausteine für die Softwareevolution

Wenn wir Software naturnah entwickeln wollen, also als evolvierbares System, wie sollte sie denn dann aufgebaut sein? In meinem vorherigen Artikel habe ich mir Gedanken über eher organisatorische Voraussetzungen für naturnahe Entwicklung gemacht. Diesmal will ich die technische Seite angehen. Oder besser: wieder angehen, denn vor Jahren schon hatte ich in diese Richtung spekuliert [1]. Damals waren meine Idee eher im Konzeptionellen verblieben - heute habe ich eine Vorstellung von ihrer Implementation.

Voraussetzung Selbstähnlichkeit

Ich glaube immer noch, dass Software nur wirklich gut evolvieren kann, wenn ihre Struktur selbstähnlich ist. Das heißt erstens, dass es in Software mehrere Ebenen gibt. Und zweitens bedeutet es, dass der grundlegende Aufbau aller Ebenen gleich ist.

Ich möchte diese Ebenen jedoch nicht Schicht/Layer nennen. Der Begriff ist überladen und deutet deshalb in die falsche Richtung. Stattdessen wähle ich Stratum; damit lehne ich mich an Abelson/Sussman an, die von Stratified Design sprechen.

Selbstähnlichkeit hat den Vorteil, dass Erfahrungen und Denken nicht ebenenspezifisch sind. Man kann auf einer beliebigen Ebene beginnen und sich sowohl nach oben wie nach unten vorarbeiten, ohne einen konzeptionellen Bruch zu erleiden.

Methoden sind etwas ganz anderes als Klassen, die wiederum etwas anderes sind als Assemblies, die wiederum ganz anders sind als Prozesse. Wenn wir mit diese Mitteln Software in unserem mentalen Modell repräsentieren, dann ist das kompliziert, weil immer wieder anders.

Eine Reduktion auf Klassen allein jedoch ist nicht möglich, da Klassen konzeptionell nichts enthalten außer Methoden. Klassen sind nicht schachtelbar. Sie sind dafür gedacht, Zustand und Funktionalität zusammenzufassen. Das war´s. [2]

Selbstähnlichkeit ist für mich die Voraussetzung, dass Systeme sich entwickeln können. Sie können in der Breite wachsen (innerhalb einer Ebene) oder sie können nach oben wachsen (Abstraktion, Aggregation) oder sie können nach unten wachsen (Verfeinerung, Spezialisierung).

Voraussetzung Unabhängigkeit

Dann glaube ich, dass die Bausteine in den Strata einer Software, unabhängig von einander sein sollten. Abhängigkeiten – statische wie dynamische – sind der Anfang allen Unwartbarkeitsübels. Dependency Injection zum Zwecke der Bereitstellung von Dienstleistungen ist keine Lösung, sondern perpetuiert das fundamentale Problem.

In der Natur finden sich keine Dienstleistungsabhängigkeiten in der Form, wie sie in Software allerorten existieren. Keinem Organismus wird eine Abhängigkeit injiziert. (Nur Parasiten injizieren sich – wir denken an Sacculina, Juwelwespe oder Ridley Scotts Alien.) Organismen brauchen einander, aber nicht in Form von “Referenzen” oder “Handles”. Sie sind vielmehr auf ihre jeweils autonom hergestellten “Outputs” angewiesen. Das ist gelebte Entkopplung.

Dasselbe gilt für den Maschinenbau oder die Elektrotechnik. Einem Motor wird kein Benzintank injiziert, auch wenn er ohne den Treibstoff nicht arbeiten kann. Benzintank und Motor werden lediglich verbunden; es gibt Berührungspunkte, aber keine Abhängigkeiten.

Allemal gibt es keine so breiten Abhängigkeiten wie die durch Interfaces üblicherweise eingegangenen. Ein Motor ist nicht von einem Chassis oder einen kompletten Restauto abhängig. Er hat verschiedene Input-Kanäle, die nur irgendwie gespeist werden müssen. In einem Motorprüfstand wird deutlich, dass das auch ganz anders als mit einem Auto geschehen kann. Dasselbe gilt für einen menschlichen Körper, der ganz ohne Herz und Lunge auskommen kann, wenn an die Gefäße eine Herz-Lungen-Maschine angeschlossen ist.

Abhängigkeiten machen Systeme starr. Evolvierbarkeit setzt daher maximale Unabhängigkeit voraus.

Voraussetzung Nachrichtenorientierung

Die Verbindung zwischen Lebewesen ist immer “nachrichtenorientiert”. Wichtiger ist aber die Nachrichtenorientierung. “Daten” fließen unidirektional von einem Lebewesen zu einem anderen, gezielt oder diffus. Folgt man dem Konstruktivismus, dann ist die Welt (und damit andere Lebewesen) gar nicht direkt erfahrbar. Wir haben lediglich eine begrenzte Wahrnehmungsbreite und empfangen Signale. Die Ausgangspunkte dieser Signale selbst haben wir nie in der Hand. Wir konstruieren sie uns aus den Signalen.

Wenn das für die Evolution der Natur so zentral ist, dann scheint es mir vorteilhaft für Software, die ebenfalls hochgradig evolvieren muss. Ihre Bausteine sollten ebenfalls nur über Nachrichten kommunizieren. Das heißt, es gibt kein Call/Response, sondern nur unidirektional fließende Datenpakete. (Inwiefern die Referenzen auf den Zustand von Bausteinen enthalten können/dürfen, lasse ich hier mal dahingestellt.)

Softwarebausteine verstehen bestimmte Nachrichten, die sie von der Umwelt empfangen. Und sie senden eine bestimmte Menge von Nachrichten an ihre Umwelt. Sendung und Empfang sind in der Natur asynchron. Zwischen Softwarebausteinen würde ich Asynchronizität jedoch nicht zwingend voraussetzen.

Die Form evolvierbarer Software

Wenn ich diese Voraussetzungen zu einer Form für Softwarebausteine zusammenfasse, dann kommt das folgende Bild heraus:

image

Ich könnte diesen Softwarebaustein “Objekt” nennen, da er zustandsbehaftet ist und über Nachrichten kommuniziert. Aber “Objekt” ist so belastet, dass ich zumindest heute auf einen neutralen Begriff ausweichen möchte. Ich nenne ihn deshalb “Holon”. Das passt zur Selbstähnlichkeit; Holons sind “Dinger”, die gleichzeitig Teil und Ganzes sind.

Jedes Holon nimmt die Umgebung durch einen “Kanal” wahr und sendet über einen weiteren “Kanal” Signale an seine Umgebung, die dann andere Holons wahrnehmen können. Wahrnehmungen (Input) verarbeitet das Holon zu Zustand und/oder Signalen (Output).

Natürlich kann jedes Holon nur eine bestimmte Menge von Signalen verarbeiten und erzeugen. Signale bzw. Nachrichten bestehen daher nicht nur aus Daten, sondern haben auch noch einen Typ oder eine Bedeutung. Die Zahl 42 mag einmal die Bedeutung einer Antwort auf die ultimative Frage haben und einmal schlicht das Alter einer Person sein.

Aus Holons lassen sich nun Verarbeitungsstrukturen auf mehreren Ebenen (Strata) bilden:

image

Meine These ist, dass Software viel besser evolvierbar wird, wenn wir sie aus Holons aufgebaut denken. Die scheinen merkwürdig eingeschränkt gegenüber unseren heutigen OOP-Objekten. Ich behaupte aber mal, dass einen eventuelle Einschränkung mehr als kompensiert wird durch das, was wir bekommen. Und das wir nur bekommen, was wir wollen – viel mehr Evolvierbarkeit –, wenn wir uns einschränken.

Wir denken mit Holons nicht mehr über Abhängigkeitsverhaue nach. Wir haben einen ganz regelmäßigen Aufbau von Software von der kleinsten Codeeinheit bis zur größten. Wir können ganz natürlich Stratified Design betreiben. Und wir bekommen Bausteine, die sich von Hause aus für asynchrone/parallel Verarbeitung eignen.

Klar, das bedeutet, wir müssen unsere Denkstrukturen ändern und Gewohntes über Bord werfen. Der in Aussicht gestellte Gewinn scheint mir jedoch groß genug, um es damit zu probieren. Und so schwer ist es ja auch nicht, es auszuprobieren. Hier das universelle Interface für Holons:

interface IHolon {
  void Process(IHolonMessage input, Action<IHolonMessage> output);
}

Im Grunde reicht sogar ein Delegat, um jeden Baustein in jedem Stratum zu beschreiben:

delegate void Holon(IHolonMessage input, Action<IHolonMessage> output);

Und die Nachrichten, die zwischen den Holons fließen, sind auch ganz einfach:

interface IHolonMessage {
    string Type {get;};
    object Data {get;};
}

Kaum zu glauben, aber ich denke, dass mit solch einfachen Mitteln sich grundsätzlich alle Softwarelösungen ausdrücken lassen. [3] Diese einfachen Mittel stellen für mich das Rückgrat evolvierbarer Software dar.

PS: Wenn in der Softwareentwicklung Eleganz wirklich einen hohen Stellenwert hat, dann wage ich mal keck zu hoffen, dass eine Softwarestruktur dieser Art doch einigen Appeal hat. Ich zumindest finde sie in ihrer Einfachheit elegant.

PPS: Ich weiß, die Holons sehen aus wie Funktionseinheiten des Flow-Designs. Natürlich gibt es da auch einen Zusammenhang. An dieser Stelle überlege ich jedoch grundlegender. Deshalb haben Holons auch nur einen Eingang und einen Ausgang.

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

Fußnoten

[1] s. ältere Artikel in der Rubrik “Software als System” in diesem Blog, insbesondere diesen und diesen Artikel.

[2] Das heißt nicht, Objekte seien nutzlos für evolvierbare Software. Nein, ich denke, wir müssen keine neue Programmiersprache erfinden, sondern die vorhandenen nur besser einsetzen.

[3] Natürlich meine ich damit nicht, dass Software bis hinunter zu Ausdrücken aus Holons aufgebaut werden sollte. Mir geht es um das Herunterbrechen von Funktionalität bis zu einer Granularität, dass man begründet zuversichtlich sein kann, ein Blatt-Holon mit wenigen Zeilen konventionellen Codes umsetzen zu können.

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...