Follow my new blog

Samstag, 28. Juni 2014

Regelmäßiges Lernen - Mein Commitment

imageGute Softwareentwicklung gibt es nicht ohne regelmäßiges Lernen. Technologisch bleibt man sonst immer weiter zurück. Aber auch neue Methoden können sonst nicht wirklich eingeführt werden.

TDD, Clean Code, NoSql, Reactive Programming, F# oder was sich sonst noch nützlich auf die Softwareproduktion auswirken könnte, kann man nicht im Kopf anschalten. Dafür braucht es vielmehr Zeit, um zu lesen, zu denken, zu üben, bevor man es in den Alltag der Produktionscodeentwicklung übernehmen kann.

Ich glaube, 20% Lernzeit während (!) der Arbeitszeit wären gut. Mehr als 10% scheinen in den allermeisten Unternehmen jedoch nicht machbar. Dann also 10% - aber nicht weniger!

Diese 10% können aus autodidaktischem Lernen für sich, Lernen in der Gruppe und Teilnahme an Kursen bestehen. Einer meiner Kunden stellt seinen Entwicklern z.B. 150 Stunden pro Jahr für das Lernen zur Verfügung. Das sind ca. 10% der Arbeitszeit, wenn ich mal 200 Arbeitstage à 8 Stunden rechne. Allerdings verplant man diese 150 Stunden in Form von Seminarteilnahmen. Das ist gut gemeint - aber kontraproduktiv. Denn wann soll denn das, was man im Seminar lernt, geübt werden? Seminarteilnehmer können ja nicht nach 2–3 Tagen Seminar, was als Lernstoff vermittelt wurde. Dafür ist unser Metier zu kompliziert. Unser Lernstoff muss geübt werden. Und nochmal geübt werden. Bevor man ihn halbwegs sicher auf Produktionscode anwenden kann.

Kein Musiker probt auf der Bühne. Kein Chirurg lernt neue Techniken am gewöhnlichen Krankenhauspatienten. So sollte es auch bei der Softwareentwicklung sein. Es braucht für Neues geschützte Übungszeit. Regelmäßig.

Das fällt schwer. Das höre ich immer wieder. Es passt einfach nicht zum vorherrschenden Mindset der 110% Auslastung aller Mitarbeiter mit Tagesgeschäft. Doch es hilft nichts. Wer nachhaltig “wirtschaften” will, der muss dafür Zeit zur Verfügung stellen. Und nicht nur fürs Lernen.

Nun mag man sagen, “Ralf, du hast gut reden. Als Berater/Trainer ist dein Leben viel einfacher. Du kannst dir Zeit nehmen, wie du willst.”

Aber das stimmt nicht. Auch ich habe ja mein Tagesgeschäft. Klar, das sieht anders aus als das eines Entwicklungsteams. Von den Prioritäten her fühle ich mich da allerdings genauso eingeengt. Für einen Entwickler mag es aussehen, als würde ich ständig lernen. Ist nicht ein Buch über Softwareentwicklung lesen, einen Artikel schreiben, ein Seminar vorbereiten Lernen?

Das stimmt in Bezug auf die Softwareentwicklung. Es stimmt aber nicht in Bezug auf die Vermittlung von Softwareentwicklung. Was für Entwickler Lernen ist, ist für mich Tagesgeschäft.

Das verwechsle ich allerdings auch oft. Deshalb muss ich einsehen, dass selbst ich, nicht genug lerne. Ich lebe sozusagen selbst noch nicht das, was ich predige. Das ist Mist. So kann ich meine Überzeugung nicht authentisch vermitteln. I need to put my money where my mouth is :-)

Das Lernversprechen

imageDas will ich, nein, das muss ich nun ändern. Da geht kein Weg dran vorbei, wenn ich als One Man Think Tank weiterhin glaubwürdig sein will. Also lege ich hier ein Versprechen ab.

Ich verspreche, dass ich fortan mindestens 10% meiner Arbeitszeit[1] dem Lernen widmen werde.

Dieses Lernen kann im Besuch von Vorträgen oder Seminaren bestehen, das kann aber auch Lesen und Üben daheim sein.

Da mein Job die Vermittlung von Softwareentwicklungsmethodiken ist, können Lerninhalte natürlich nicht Softwareentwicklungsmethodien sein. Mein Lernen muss vielmehr auf der Meta-Ebene bzw. im Allgemeineren stattfinden.

Oder ich könnte auch sagen: Ich muss beim Lernen dasselbe Gefühl haben, wie meine Kunden. Einerseits muss ich es wollen, andererseits muss es mir aber auch wehtun. Auch ich muss beim Lernen spüren, dass ich eigentlich etwas anderes dringender tun müsste.

Aktivitäten auf die das für mich zutrifft, sind z.B. eine Sprache lernen, Meditation, die Beschäftigung mit “Sachthemen”.

Für Sie mögen das Freizeitaktivitäten sein, für mich gehört das jedoch im weiteren Sinn zum Job:

  • Mein Job ist es, mit Sprache umzugehen, sowohl mit natürlicher wie mit formaler. Auf die eine oder andere Weise. Deshalb ist es wichtig, dass ich meinen “Sprachmuskel” fit halte. Jede Sprache, die ich lerne oder deren Kenntnis ich verfeinere, macht es mir leichter, zu kommunizieren, was ich vermitteln will.
  • Mein Job ist es, mich vielen Einflüssen auszusetzen und oft zu reisen. Innere Ruhe und Gelassenheit sind dann wichtig, um in dem Rahmen eine balancierte und authentische Botschaft zu vermitteln. Medidation und die Beschäftigung mit spirituellen Themen hilft, diesen Zustand herzustellen.
  • Die Softwareentwicklung profitiert davon, sich durch andere Disziplinen oder sogar ganz allgemein “durch das Leben” informieren zu lassen. Bauarchitektur, Biologie, Physik, Soziologie usw. halten viel bereit, von dem wir lernen können. Darüber hinaus kann meine didaktische und methodische Praxis als Trainer nur davon profitieren, wenn ich mich in anderen Bereichen umschaue (z.B. systemische Analyse, Lernpsychologie). Ich muss also “Sachthemen” erkunden - und das durchaus, ohne immer genau zu wissen, wann ich welches wie anwenden kann. Sozusagen Grundlagenforschung statt angewandte Forschung.

Natürlich habe ich in der Vergangenheit diese Aktivitäten schon betrieben - nur nicht systematisch. Da war es Freizeit und ich konnte jederzeit damit aufhören. Nun will ich das ändern. Darin besteht mein Commitment.

Ich verspreche, jede Woche mindestens 4 Stunden wie folgt ins Lernen und Üben zu investieren:

  1. Sprachenlernen: Ich widme jeden Arbeitstag 20–30 Minuten dem Lernen einer Sprache. Derzeit ist das Französisch. 5x20=100 Minuten, d.h. 1,66 Stunden.
  2. Meditieren: Ich mediere jeden Tag 10–15 Minuten. 7x10=70 Minuten, d.h. 1,16 Stunden.
  3. Sachthemen: Ich lese jeden Arbeitstag 15–30 Minuten über ein Sachthema. 5x15=75 Minuten, d.h. 1,25 Stunden. Dazu mögen über das Jahr verteilt Konferenzen oder Seminare kommen, wo ich mich en bloc länger mit einem Thema befasse. In diesem Jahr waren das z.B. schon eine Konferenz zum Thema Unternehmertum und ein Seminar über Prozessmanagement.

Das sind Aktivitäten, von denen ich weiß, dass sie für mich wichtig sind. Ich muss hier regelmäßig am Ball bleiben. Dennoch fällt es mir schwer, sie auch ständig während des Tagesgeschäftes auf dem Zettel zu haben.

Jeden (Arbeits)Tag 15–30 Minuten mit so einer Aktivität verbringen, führt das denn zu Fortschritt? Ja, das glaube ich ganz sicher. Nicht kurzfristig, aber mittel- und langfristig. Es gibt ja auch keine Rüstzeiten und spezieller “mental state” muss auch nicht aufrechterhalten werden. Außerdem steht es mir jederzeit frei, mehr Zeit einer dieser Aktivitäten einzuräumen.

Soviel zu meinem Versprechen. Und wie dokumentiere ich, dass ich es einhalte?

Ich benutze die App Lift, um die Durchführung zu protokollieren.

imageimage

imageimage

Nach Abschluss einer Aktivität hake ich sie in der App ab. Das an sich ist schon ein kleiner Erfolg. Noch motivierender ist es jedoch, in der Übersicht zu sehen, wie kontinuierlich ist dabeigeblieben bin.

Wer mag, kann meinen Fortschritt verfolgen. Ich habe die lift-Aktivitäten öffentlich gemacht:

Spätestens in 3 Monaten berichte ich dann hier, wie es mir mit der Erfüllung meines eigenen Anspruchs ergangen ist. (Dass ich unterwegs nicht mogle, müssen Sie mir glauben. Ich mache also nur einen lift-Haken, wenn ich wirklich eine Aktivität durchgeführt habe.)

Und nun: Ich bin genauso gespannt wie Sie :-)

Let the learning begin…


  1. Meine Arbeitszeit ist nicht so klar abgezirkelt wie die eines Angestellten. Als Freiberufler bin ich sehr frei, was Zeit und Datuer meiner Arbeit angeht. Außerdem verschwimmen Arbeit und Freizeit bei mir. Mein Versprechen bezieht sich der Einfachheit halber auf eine 40 Stunden Woche. Ich verspreche also 4 Stunden Lernen pro Woche.

Montag, 9. Juni 2014

Die wichtigste Rolle in der Softwareentwicklung

Natürlich ist Softwareentwicklung eine Tätigkeit, an der viele beteiligt sind. Alle Rollen sind wichtig.

Und doch… ich glaube, es gibt eine Rolle, die ist wichtiger als andere. Sozusagen erste unter gleichen. Das ist die Rolle des Product Owner (PO).

Nicht die Programmierer sind die Wichtigsten, nicht die Qualitätssicherer, sondern der PO. Das stürzt hoffentlich niemanden in Ärger oder Verzweiflung ;-)

Wichtiger ist der PO, weil er die Softwareentwicklung klammert. Er hat zwei Hüte auf. Er kippt einerseits in den Produktionsprozess vorne Anforderungen als Input hinein. Andererseits nimmt er am Ende den Output entgegen und gibt dazu Feedback. Er ist Sender und Empfänger, Quelle und Senke.

Damit ist er für den Kurs der Softwareentwicklung verantwortlich. Er ist wie ein Kapitän. Der Steuermann mag lenken, der Ausguck mag vorausschauen, der Maschinist mag für Vortrieb sorgen; und alle entscheiden dabei situativ.

Doch allein der Kapitän entscheidet strategisch, d.h. im Hinblick auf das zu erreichende Ziel. Er gibt den Rahmen für alle anderen vor.

Genauso der PO. Er hat als Ziel den Nutzen für den Anwender im Auge. Dafür soll Software mit bestimmten Eigenschaften bereitgestellt werden. Wie, das entscheidet der PO. Er ist Stellvertreter des Kunden auf dem Projektschiff, so wie ein Kapitän Stellvertreter des Reeders auf einem Handelsschiff ist.

Selbst der Softwarearchitekt ist dem PO untergeordnet. Architektonische Entscheidungen müssen sich immer im Rahmen dessen bewegen, was der PO an Anforderungen stellt.

Die wichtigste Aufgabe des Product Owner

Besonders schwierig macht es die Aufgabe des PO, dass er als Klammer sowohl am Anfang wie am Ende des Produktionsprozesses steht.

Deshalb möchte ich betonen, was die wichtigste Aufgabe des PO ist. Welchen Hut sollte er vor allem aufhaben?

Wikipedia widmet dem PO 14 Sätze. Davon ist allerdings nur ein Teilsatz der aus meiner Sicht wichtigsten Aufgabe des PO gewidmet: Er trifft “die Entscheidung darüber, ob die vom Entwicklungsteam am Ende jedes Sprints gelieferte Funktionalität akzeptabel ist.”

Das vor allem muss der PO tun: akzeptieren. Er muss Lieferungen von Programmierung und QS prüfen und dazu Feedback geben. Im besten Fall akzeptiert er das Gelieferte, im schlechteren Fall verweigert er die Weitergabe und muss Nachbesserungen anweisen.

Am wichtigsten ist der PO also in seiner Funktion als Senke, als schließende Klammer.

Die Literatur hingegen betont vor allem seine Funktion als Quelle, als öffnende Klammer. Da wird von Backlog, Priorisierung, User Stories, Story Points usw. gesprochen; das alles gehört zum PO als Sender von Aufträgen an das Restteam.

Natürlich, es geht nicht ohne klare Aufträge. Anforderungsdefinition ist eine rechte Kunst. Da braucht es auch viel Dialog zwischen Restteam und PO.

Aber die Anforderungsdefinition ist nicht die wichtigste Aufgabe des PO, weil sie nur eine Folge der wichtigsten Aufgabe ist. Der PO will nicht beauftragen, sondern in Empfang nehmen. Nur weil er in Empfang nehmen will, muss er wohl oder übel beauftragen. Aber je weniger Aufwand er darauf verwenden muss, desto besser.

Das Abnehmen, das Akzeptieren ist aber nicht nur für den PO bzw. den weiter downstream gelagerten Anwender/Kunden wichtig, sondern auch für das Restteam.

Indem der PO nämlich zuallererst sich auf das Akzeptieren konzentriert, stiftet er für das Restteam Sinn. Dadurch, dass er geradezu sehnsüchtig auf die nächste abzunehmende Veränderung wartet, weiß das Restteam, wer es braucht, wofür es sich anstrengt. Der PO als schließende Klammer stellt ein Ziel dar, auf das sich jeder ausrichten kann. Kohärenz wird geschaffen. Insofern ist der PO sogar als leader anzusehen.

Folgen eines Missverständnisses

Leider wird die Rolle des PO meist missverstanden. Entweder wird er nicht als die wichtigste Rolle angesehen. Entwickler scheinen am wichtigsten, immerhin produzieren die das “Objekt der Begierde” für den Kunden. So schwer kann das doch auch nicht sein, oder? Am besten wissen es womöglich sogar die Entwickler, was gebaut werden sollte.

Das Resultat ist ein insgesamt schwacher PO. Er ist halbherzig bei der Sache - wahrscheinlich, weil er sich erstens diese Aufgabe nicht gewünscht hat und zweitens auch noch eine Menge anderer Dinge zu tun hat.

Ein schwacher PO - oder noch schlimmer: ein fehlender - führt dann zu schlechtem Input für das Restteam. Nach der Gleichung garbage in = garbage out führt das wiederum zu schlechtem Output. Und der wiederum führt zu Nachbesserungen. Das verringert die Kapazität des Restteams für neue Features, das erhöht die Verschwendung durch Produktion von Unnötigem und das nagt am Vertrauen des Kunden, weil der nur unzuverlässig und mit suboptimaler Qualität beliefert wird. Und zu allem Überfluss steigen noch die Supportkosten und es sinkt die Motivation.

Oder, selbst wenn der PO als wichtig angesehen wird, dann im üblichen Sinn: als sprudelnder Quell von Anforderungen. Er nimmt dann seine Aufgabe ernst und produziert User Stories, dass es nur so eine Freude ist. Er spricht mit dem Support, er spricht mit dem Kunden, er ist da für Fragen vom Restteam. Das Backlog wächst, die Entwicklung hat zu tun. Die Klammer ist geöffnet.

Doch am Ende… da fehlt es an Zugkraft. Der PO beauftragt stark - und zieht am Ergebnis zu schwach. Er hat wenig Erwartung, wann etwas geliefert werden soll. Und wenn, dann lässt er sich einladen zu einer Präsentation dessen, was das Team meint, präsentieren zu können. Im Zweifelsfall hat er womöglich sogar nicht einmal genügend Entscheidungskompetenz, um Abweichungen “vom Plan” akzeptieren oder ablehnen zu können.

Aus womöglich ordentlichem Input wird auf diese Weise Output von ungewisser Qualität. Da der PO nicht maximal daran interessiert zieht, gibt es endgültiges (!) Feedback oft erst Tage oder Wochen nach Fertigstellung.

Das führt zu Ungewissheit, Motivationsschwund, Verschwendung. Die Zuverlässigkeit des Restteams wird auf diese Weise auch nicht erhöht.

Die Qualität des Teams bestehend aus PO + Restteam(Programmierung, QS) steht und fällt also mit dem PO. Ein schwacher PO wird genauso vom Restteam erkannt wie ein schwacher Lehrer oder schwache Eltern. Der mag dann nett sein - aber systematisch und verlässlich für den Kunden muss man dann nicht produzieren.

Fazit

Softwareentwicklung ist kein Ponyhof. Es ist ein hartes Business, in dem man umso besser besteht, je klarer die Richtung ist. Einer, der Richtung vorgibt, ist der PO. Das tut er aber nicht durch Backlog-Einträge, sondern durch seinen unermüdlichen Willen, produziertes Abzunehmen.

Das hat auch einen ökonomischen Grund: Statt neue Aufträge in das Restteam zu stopfen, sollten angefangene Aufträge herausgezogen werden. Es ist sonst unklar, ob der Arbeitseinsatz gelohnt hat. Nur kann auch Wert für den Kunden entstehen. Den freut ja nicht, wenn das Restteam busy ist, sondern nur, wenn er etwas brauchbares in die Hand bekommt.

Ich habe hier den Begriff PO gebraucht, weil er sich für diese Rolle eingebürgert hat. Ich sehe die aber nicht an Scrum geknüpft. Und ich vermute sogar, dass rundum agiles Vorgehen weniger wichtig ist als ein starker PO, der weiß, dass die Abnahme seine vornehmste Aufgabe ist.

Ein klares Ziel und klares, schnelles Feedback – das ist das Geheimnis erfolgreicher Softwareentwicklung. Das ist oft der Fall am Anfang eines Softwareprojektes/-produktes. Daran erinnern sich alle immer gern zurück. Mindestens diesen Zustand aufrecht zu erhalten, sollte das Ziel jedes Projekt-/Produktmanagements sein.

Wenn ich Softwareprojekte/-produkte gesehen habe, die im Verhältnis zu ihrer Codesauberkeit gut im Fluss waren, dann hat das immer an starken POs gelegen.

Oder umgekehrt: Wo der PO schwach oder gar abwesend war, hat es immer massiv gehakt - auch wenn das Restteam motviert und kompetent war.

Ein PO wird der Wichtigkeit seiner Rolle also am besten gerecht, wenn er stets zuerst schaut, was es abzunehmen gibt. Das erfragt er aber nicht beim Team, sondern hat eine genaue Erwartung dazu. Denn darüber hat er schon vorher mit dem Team verhandelt - und das nicht vor Wochen, sondern gestern.

Jeden Tag etwas abnehmen - so sollte der Rhythmus des PO sein.

Und nur, wenn dem Restteam die Aufträge ausgehen, denkt er daran, was er als nächstes “einkippen” sollte.

Im Stil des agilen Manifests könnte ich so formulieren: acceptance over specification.

Dienstag, 3. Juni 2014

Klein ist ökonomisch

Es kommt auf die Größe an – zumindest bei der Wartbarkeit (oder besser: Evolvierbarkeit). Über Helge Nowaks Präsentation bin ich auf diesen Text gestoßen und darüber dann auf einen Video-Vortrag:

Viktigste faktorer for å redusere teknisk gjeld - Dag Sjøberg from Smidigkonferansen on Vimeo.

Keine Angst, Sie müssen nun nicht Ihr Norwegisch abstauben. Ich denke, interessante Einsichten lassen sich auch aus den Vortragsfolien ziehen.

Vorab aber die Geschichte hinter dem Vortrag: Es wurde ein Experiment zu Wartungskosten für Softwaresysteme gemacht. Dazu wurde dasselbe System bei vier Softwarehäusern in Auftrag gegeben. Anschließend wurden alle vier Systeme gleichermaßen genutzt und also mit realen Daten befüllt. Und dann hat man allen Softwarehäusern einen Änderungsauftrag erteilt.

Mit dem Experiment sollte herausgefunden werden, welche Merkmale von Software mit guter/schlechter Wartbarkeit korrelieren. Deshalb hat man auch noch Softwarequalitätsexperten befragt, wie sie die Wartbarkeit der Systeme einschätzen.

Das spannende Ergebnis: Die Experten lagen daneben mit ihren Metriken. Vorhersagekraft hatte allein die Zahl der Codezeilen (Lines of Code, LOC).

image

Verblüffend, oder?

Denn dem stehen diese Vorhersagen gegenüber:

image

Systeme B und D sollten die beste Wartbarkeit aufweisen, A und C die schlechteste.

Nun könnten Sie sagen, der Aufwand für B und D lag nicht soviel über dem von A wie C. Für B mit dem besten Vorhersagewert war nur ca. 50% mehr Aufwand als für A nötig. Für D nur knapp 100% mehr. Das sind doch keine großen Missweisungen wenn man an das Verschätzen bei der Softwareentwicklung im Allgemeinen denkt.

Gegen diese Interpretation spricht für mich aber zweierlei: Zum einen ist der Vorhersagewert von A der schlechteste und auch noch für sich genommen grottig. Zum anderen steht hinter den schlechteren Wartungsaufwänden bzw. besseren Vorhersagewerten ein deutlich höherer Anfangsaufwand:

image

Meine Norwegisch-Kenntnisse geben mir ein, hier wird gefragt, ob wirklich mehr Aufwand zu geringeren technischen Schulden (lies: mehr Evolvierbarkeit) geführt hat. Leider muss die Antwort Nein lauten. Die laut Vorhersage besser wartbaren Systeme haben zwar knapp 100% bzw. 250% der Aufwands erfordert, der in den Letztplatzierten gegangen ist. Doch trotzdem hat der sie am Ende deutlich geschlagen.

Bessere Metrikwerte waren also teuer – und haben es nicht gebracht. Das ist bitter, oder?

Das am besten wartbare System hat pro Person am wenigsten Zeit in der Entwicklung gekostet und am wenigsten LOC enthalten.

Ist das eine triviale Aussage? Hm… ich glaube nicht. Denn sonst hätten die Experten ja besser geurteilt.

Schlussfolgerungen

Ich denke, es lassen sich aus dem Ergebnis einige Schlussfolgerungen für die Praxis ziehen. Wenn weniger LOC bessere Evolvierbarkeit bedeuten, dann müssen wir alles (naja, zumindest vieles) daransetzen, weniger LOC herzustellen. Und das geht so:

1. YAGNI

Weniger LOC beginnen nicht so sehr beim Entwickler, sondern eher beim Kunden bzw. beim PO. Er sollte noch schärfer darüber nachdenken, was wirklich, wirklich an Features benötigt wird. Und er sollte in noch dünneren Inkrementen codieren lassen, um schneller sagen zu können “Good enough!”. Ich bleibe also dabei, das Spinning eine Kernpraxis jeder Softwareentwicklung sein sollte.

Code erst gar nicht zu schreiben, ist das beste Mittel, um LOC zu reduzieren.

Aber das geht natürlich nicht nur den PO etwas an, sondern auch die Entwickler. Gern wird auf Vorrat implementiert, weil man ja soviel Erfahrung hat, was da noch alles kommen mag. Dann wird vorhergesehen und flexibilisiert, was das Zeug hält. Wiederverwendbarkeit ist ganz beliebt als herzustellendes Merkmal – auch wenn niemand weiß, was wie viel wiederverwendet wird.

2. KISS

Was dann implementiert wird, sollte so einfach wie möglich sein. Da verschwimmt manchmal die Grenze zwischen YAGNI und KISS, aber ich denke, jeder kennt Beispiele, wo etwas kompliziert gelöst wurde, wo es einfacher gegangen wäre. Der Grund: Unkenntnis, vermeintlicher Zeitmangel.

Auch für Code gilt Pascals (oder Goethes?) Ausspruch: Wenn ich mehr Zeit gehabt hätte, hätte ich mich kürzer gefasst.

Wie das Experiment zeigt, ist Zeitaufwand gesteckt in weniger LOC aber gut investierte Zeit. Die macht die später unabsehbaren “Wartungsarbeiten” kostengünstiger.

Natürlich gilt es da eine Balance zu finden. Mancher elegante Einzeiler ist am Ende schwerer zu evolvieren als etwas gesprächigerer Code.

3. Knappe Programmiersprache

Die LOC-Frage wirft eine zweite, womöglich schon zu den Akten gelegte auf: Welche Programmiersprache sollte benutzt werden, um das Nötige simpel zu codieren?

Früher ging es um Compiler- und Ausführungsgeschwindigkeiten. Heute ist das nicht mehr so ein großes Thema. Stattdessen sollte es um Knappheit (terseness) gehen. Natürlich Knappheit, die zur Lesbarkeit beiträgt. Das kann man von PERL oder APL eher nicht sagen, aber wohl z.B. von F#.

Welche Sprache bietet gute Abstraktionen, welche Sprache bemüht sich um “Rauschunterdrückung”? Java hat da heute für mich z.B. eher einen hinteren Platz. C# scheint mir im Mittelfeld. Und wie steht es mit Modernem wie Go, Exlixir, Swift?

Einerlei. Ich will hier für keine Sprache werben, sondern nur auf ein Mittel zur Reduktion der LOC für mehr Evolvierbarkeit aufmerksam machen. Die Sprachfrage sollte nicht leichtfertig abgetan werden mit dem Verweis aus die Tradition: “Wir haben halt immer schon in X entwickelt.”

4. Granulare Abstraktion

Eine Programmiersprache bietet mehr oder weniger Abstraktion. Mehr bedeutet gewöhnlich weniger LOC. Noch mehr bedeutet noch weniger LOC – aber ab einem gewissen Punkt geht das auf Kosten der Universalität. Beispiel SQL: damit lassen sich sehr knapp Anweisungen ausdrücken, aber SQL ist nicht computationally complete.

Durch die Wahl einer 3GL lassen sich die LOC also nur auf ein gewisses Maß reduzieren. Weiter muss es dann mit DSLs (Domain Specific Languages) gehen. Die gibt es nur nicht für alle Problemdomänen. Und es ist nicht zu erwarten, dass sich das grundlegend ändert. Einzelne Teams haben es schon schwer genug, Bibliotheken mit vernünftigen Abstraktionen zu entwickeln, da sind eigene DSLs in weiter Ferne. Sie haben ihren Platz – aber ihr Beitrag zur LOC-Reduktion für den Mainstream wird gering bleiben.

Wichtiger finde ich es daher, mit den Mitteln der gewählten 3GL eigene Abstraktionen auf unterschiedlichem Niveau zu schaffen. Die Mittel sind Container wie Funktion, Klasse/Modul, Komponente, (micro)Service.

Mein Annahme ist, dass sich das Versuchsergebnis auf verschiedene Größenordnungen übertragen lässt. Zwei Funktionen, die dasselbe leisten, sind je nach LOC unterschiedlich evolvierbar. Zwei Klassen, die dasselbe leisten, sind je nach LOC unterschiedlich evolvierbar. Usw. usf.

Kleine Funktionen, kleine Klassen, kleine Komponenten, kleine Services sind also anzustreben. Funktionen mit 3000 LOC, Klassen mit 100.000 LOC, die Abwesenheit von Komponenten und Services… das alles sind Zeichen der Unwartbarkeit.

Wer Evolvierbarkeit will, der sollte sich also stetig um kleine Container bemühen und um Container auf weiteren Abstraktionsebenen oberhalb von Klassen. Wo es nur Funktion, Klasse, Softwaresystem und das auch noch ohne LOC-Begrenzung gibt, ist der Monolith vorprogrammiert.

Wie kommen Sie denn aber zu kleinen Funktionen und Klassen? Die Forderung ist ja auch schon älter, ohne dass sie einen spürbaren Effekt gehabt hätte. Manche sagen, Funktionen sollten nur 7 oder 20 Zeilen haben. Andere sagen, sie sollten nicht länger als eine Bildschirmseite sein (aber mit welcher Auflösung).

Ich glaube, die Forderung nach einem bestimmten max. Zeilenzahl bringt uns nicht weiter. Wir brauchen einen Ansatz des Softwareentwurfs, der ganz natürlich zu kleinen Funktionen und Klassen führt. Die bisherige Objektorientierung leistet das nicht. Wir müssen nachbessern.

In meiner Codierungspraxis gibt es inzwischen keine Funktion mehr, die länger als 50 Zeilen ist (und mehr als Triviales tut). Nicht, weil ich mich durch StyleCop warnen lasse, sondern weil ich Software mit Flow-Design nur so entwerfen kann, dass alle Funktionen klein sind. Wenn Sie wissen wollen, wie das funktioniert, folgen Sie doch dem “Book in Progress” von Stefan Lieser und mir: The Architect´s Napkin Kata für Kata.

Eine größere Zahl von Funktionen und Klassen braucht dann natürlich wieder Container. Das Softwaresystem als Ganzes ist zu groß. Deshalb gehören für mich Komponenten- und Serviceorientierung ganz natürlich zu den Maßnahmen, die LOC pro Container zu reduzieren. Die einzuführen ist aber natürlich nochmal eine andere Nummer als die LOC-Reduktion bei den schon in Gebrauch befindlichen Containern Funktion und Klasse.

Aber es lohnt sich, denke ich. Durch Komponenten und Services wird es nicht nur mit LOC besser pro Container, sondern auch mit der Produktionseffizienz. Denn durch die expliziten Kontrakte kann an Komponenten und Services viel besser arbeitsteilig parallel gearbeitet werden. Darüber hinaus bieten Services die Chance, im selben Softwaresystem mehrere Runtimes/3GLs einzusetzen. Plattformneutrale Kontrakte machen es möglich. Ausführlicher dazu in The Architect´s Napkin – Der Schummelzettel.

Ziel ist in jedem Fall, mit den vielen kleinen Containern ein eigenes Domänenvokabular, gar eigene “Domänensätze” zu formulieren. Mit dem können Sie dann immer neue Geschichten (user stories) “schreiben”.

5. Geschichten trennen

Container sind ein technisches Granulat. Ich denke, es gibt aber auch aus Sicht von Kunde/Benutzer die Möglichkeit, granularer zu entwickeln, d.h. mehr Funktionseinheiten mit jeweils weniger LOC zu bilden.

Das Problem beginnt hier wieder beim Kunden. Der will oft “alles unter einem Hut”. Der sucht die “one size fits all” Anwendung. Die wächst und wächst dann und enthält alle LOC.

Was aber, wenn die Anforderungen nicht durch nur eine Anwendung, sondern durch viele umgesetzt würden. Nicht ein Icon auf dem Desktop, nicht eine URL im Intranet für alles, sondern viele.

Die Smartphones machen es vor. Statt einem Boliden wie Outlook vertrauen wir uns einem Schwarm aus kleinen Apps für Email, Kalender, Aufgaben, Notizen an. Viele Spezialisten statt ein Generalist. Das sind viele kleine Zweige unabhängiger Evolutionsmöglichkeit.

Jede App ist auf eine Domäne spezialisiert, erzählt sozusagen eine eigene Geschichte. Warum nicht dasselbe tun mit CRM, ERP, Buchhaltung, Qualitätsmanagement, Vertragsverwaltung usw. usf.? Das gesamte Softwaresystem enthält dann immer noch 100% aller LOC – nur ist es unterteilt in Apps mit jeweils einem Bruchteil der LOCs. Die lassen sich für sich leichter evolvieren.

Und innerhalb von Apps können Sie weiter Geschichten trennen. Apps müssen keine Monolithen sein, sondern können aus Modulen bestehen.

Am Ende geht es also nicht um ein Softwaresystem, sondern um einen bunten Strauß ein Modulen in Apps zusammengefasst. Das ist dann nicht eine monolithische Codebasis. Vielmehr gibt es viele schmale Schnitte durch die Anforderungen: Durchstiche. Jeder macht für sich Sinn. Jeder kann getrennt von anderen evolvieren. Änderungsaufträge werden sich meist auf einzelne Module beziehen. Die gesamte Codebasis steht also gar nicht mehr zur Debatte.

Fazit

Ich denke, das Ergebnis des Experiments bestätigt ein Bauchgefühl, das wir immer hatten. Zeit, dass wir es ernst nehmen. Packen wir die LOC bei den Hörnern und reduzieren, wo wir können.

Wo der LOC-Haufen schon groß ist, geht es nur mit Refaktorisierungen. Wo immer wir aber neuen Code schreiben, sollten wir uns mit den beschriebenen Mitteln bemühen, die LOC gering zu halten. Prevention over refactoring ;-)

Kleiner Code, Code mit weniger LOC ist unterm Strich einfach ökonomischer. Das zählt für unsere Kunden.

Sonntag, 18. Mai 2014

Zuschauen beim Softwareentwurf

Konzepte, Notationen, Methoden auf Papier sind geduldig. Darüber zu lesen, ist eine Sache. Sie dann aber anzuwenden, auch mit dem besten Willen, eine andere. Was im Artikel oder im Buch noch verständlich war und einfach aussah, erweist sich in der Praxis schnell als knifflig. Der Transfer fällt schwer – und dann lässt man es einfach sein und macht weiter wie bisher.

Dem möchten Stefan Lieser und ich nun etwas entgegenstellen. Wir sind überzeugt, dass leichtgewichtiger Softwareentwurf möglich und wünschenswert ist. Wir finden, dass er mit Flow-Design und Softwarezellen vor dem Hintergrund des Softwareuniversums wirksam ist. Und wir wollen das nun auch live demonstrieren.

imageBisher haben wir dazu viel geschrieben, in diesem Blog, in der dotnetpro und anderen Zeitschriften und schließlich auch in einem Buch: The Architect´s Napkin – Der Schummelzettel.

Was in den Artikeln über Jahre durch eine Evolution gegangen ist, fasst das Buch zusammen. Es ist eine Referenz unserer Konzepte und Notationselemente. Wir benutzen es als Schulungsunterlage in unseren Clean Code Developer Trainings z.B. bei der CCD Akademie. Es ist bei leanpub.com und sogar bei amazon erhältlich.

Wir wir erleben, braucht es einige Übung, um vom traditionellen schwergewichtigen Entwurfsdenken – das deshalb oft vermieden wird – auf diesen Ansatz umzuschalten. Bei aller Leichtgewichtigkeit ist er doch sehr anders.

In Trainings können wir das anleiten und begleiten. Was aber danach?

Für die Zeit danach bzw. zwischen Trainingseinheiten, für das Selbststudium haben wir nun ein gemeinsames Buchprojekt gestartet:

image

In diesem Buch wenden wir unsere Methode an. Wir lösen mit ihr kleine und große Aufgaben aus dem Coding Dojo der CCD School.

Das tun wir jedoch nicht wieder nur im Text, sondern auch per Video. Und die Resultate stehen in einem öffentlichen Git-Repository.

Zu jeder Kata führen wir den Entwurf live durch. Wir treffen uns online ohne weitere Vorbereitung und gehen die Anforderungen gemeinsam an. Hier als Beispiel der Entwurf zur ersten Kata im Buch. Die ist natürlich noch klein und einfach, doch sie zeigt den grundsätzlichen Ansatz:

In dieser Weise geht es weiter mit den anderen Katas bis zu Application und Architecture Katas, die wir dann verteilt implementieren.

Das Buch dient der Zusammenfassung von Video und Code. Es destilliert das Wichtigste nochmal zum Nachlesen heraus. Denn in Text lässt sich leichter navigieren als in einem Video. Und es kommentiert und ergänzt den live Entwurf.

Wir hoffen, in dieser Weise einem stiefmütterlich behandelten und zu Unrecht als trocken oder gar irrelevant angesehenem Thema neues Leben einzuhauchen. Softwareentwurf ist ein systematischer Prozess unter Anwendung einer Methode. Dabei kann man nun zuschauen. Das zeichnet ein realistisches Bild des Vorgehens. Das nimmt hoffentlich Unsicherheit.

So wie wir Software entwickeln, so arbeiten wir auch an dem Buch: agil. Es ist nicht fertig, sondern wächst in Inkrementen. Das erste Inkrement veröffentlichen wir heute. Weitere Releases folgen in den nächsten Wochen.

So können wir aus unserer Erfahrung bei der Videoaufzeichnung, beim Schreiben, beim Publizieren lernen. Und Feedback aus der Community können wir auch einfließen lassen.

Ich würde mich freuen, wenn Sie Lust hätten, uns beim Softwareentwurf zuzuschauen. Über neue Releases erfahren Sie bei Twitter hier und hier.

Mittwoch, 9. April 2014

Wichtiges verlässlich erledigt kriegen

Erledigt wird nur, was dringend ist. Ich denke, darin stimmen wir überein.

Aber es gibt Wichtiges und es gibt Dringendes. Beides muss erledigt werden – nur schiebt sich das Dringende scheinbar oft, allzu oft vor das Wichtige.

Das Wichtige

Das ist misslich und früher oder später gefährlich, denn das Wichtige ist ja das, was getan werden muss. Das macht seine Definition aus: Was bei Unterlassung über kurz oder lang zu einer Gefährdung der Existenz eines Systems führt, ist wichtig.

Ein Beispiel: Der Zweck einer Softwareschmiede ist (zumindest), mit Software soviel Geld zu verdienen, dass die daran beteiligten Menschen auf unbestimmte Zeit, d.h. jetzt und in Zukunft ihr Auskommen haben.

Im Hinblick auf diesen Zweck ist es unter anderem wichtig...

•    fähige und motivierte Menschen zu beschäftigen (Personalwesen),
•    attraktive Software herzustellen (Softwareentwicklung),
•    die Software dem Markt bekannt zu machen (Marketing),
•    für die Software Kunden zu bekommen (Vertrieb),
•    Kunden zu betreuen (Support, Schulungen)
•    mit Kunden und Lieferanten und Mitarbeitern abzurechnen (Buchhaltung)
•    Steuern zu zahlen (oder auch zu sparen) (Buchhaltung, Steuerberatung)
•    den Markt zu beobachten und Strategien zu definieren (Geschäftsführung)

Wenn eine dieser und weiterer Wichtigkeiten für längere Zeit unbeachtet bleibt, dann wird die Existenz der Softwareschmiede bedroht.

Nicht wichtig ist gewöhnlich hingegen, einen speziellen Mitarbeiter zu bekommen/halten, eine bestimmte Rechnung zu schreiben, ein spezifisches Feature einzubauen, einen bestimmten Kunden zu bekommen, einen speziellen Rechner zu kaufen usw.

Einzelnes ist nicht wichtig, sondern höchstens dringend. Oder wenn Einzelnes wichtig ist, dann ist es eine systemrelevante Größe. Dann ist Gefahr im Verzug!

Da nun selbstverständlich ausschließlich getan werden soll, was unter das Dach von etwas Wichtigem gehört, ist das Dringende immer auch etwas Wichtiges.

Damit schließt sich der Kreis: Wichtiges wird also doch getan. Zumindest sobald es dringend geworden ist. Das bedeutet unzuverlässig. Und das bedeutet oft spät. So spät, dass die Arbeit sich ausnimmt wie krampfhaftes Zucken, denn koordiniertes Voranschreiten.

Wie kann das verhindert werden?

Das Dringende

Wichtiges und Dringendes sind mithin keine Gegensätze. Dringendes ist vielmehr eine Sonderform des Wichtigen. Was es so besonders macht, das ist seine Konkretheit in Bezug auf Zustände.

Dringendes hat einen konkreten Ziel- oder Erledigungszustand sowie einen existenzbedrohenden Zustand. Immer ist es an Zeit gekoppelt, oft auch an einen Termin. Erledigung des Dringenden soll den Zielzustand herstellen; bleibt das Dringende hingegen unerledigt, tritt der existenzbedrohende Zustand ein.

Beispiel 1: Steuererklärung. Steuern zu zahlen, ist wichtig. Deshalb muss jährlich eine Steuererklärung abgegeben werden. Diese Tätigkeit ist jedoch nicht per se dringend. Sie wird erst mit der Zeit dringend, wenn der Abgabetermin näher rückt. Verstreicht der Abgabetermin ohne Steuererklärung, kann das existenzbedrohende Folgen haben.

Beispiel 2: Angebotsabgabe. Aufträge zu gewinnen, ist wichtig. Deshalb müssen immer wieder Angebote abgegeben werden. Oft unterliegt diese Abgabe einem Termin. Ein Angebot abzugeben ist jedoch nicht per se dringend. Es wird erst mit der Zeit dringend, wenn der Abgabetermin näher rückt. Verstreicht der Abgabetermin ohne Angebot, kann das – zumindest wenn es häufiger geschieht – existenzbedrohende Folgen haben.

Beispiel 3: Geldreserve. Eine Geldreserve zu haben, ist wichtig. Nur so können Schwankungen im Umsatz ausgeglichen werden, um weiterhin Verbindlichkeiten nachzukommen und Löhne zu zahlen. Deshalb ist die Aufstockung der Geldreserve jedoch nicht per se dringend. Sie wird es erst, wenn sich die Geldreserve dem Nullpunkt nähert. Allemal wenn die Geldreserve auf Null ist, ist die Existenz bedroht, sofern die Umsätze zu schwach sind.

Zielzustand und existenzbedrohender Zustand sind in den Beispielen klar. In den ersten Beispielen ist der Wechsel vom aktuellen Zustand in den einen oder anderen quasi binär und termingebunden. Im dritten Beispiel hingegen ist er graduell und nicht termingebunden, sondern wertgebunden.

Wann wird eine Tätigkeit oder allgemeiner der Eingriff in die Entwicklung eines Zustands nun dringend? Wenn das Risiko groß wird, in der verbleibenden Zeit den Zielzustand nicht zu erreichen.

image

Das Risiko ist an den Aufwand gekoppelt. Ist der Aufwand sehr klein und auch nicht selbst noch mit Unwägbarkeiten behaftet, gibt es bis kurz vor Erreichen des existenzbedrohenden Zustands keine Dringlichkeit. Ist der Aufwand hingegen groß oder gar unbekannt, stellt sich Dringlichkeit schon lange vor Erreichen des existenzbedrohenden Zustands ein.

Zu Beispiel 1: Wie groß ist der Aufwand für eine Steuererklärung? Bei mir dauert es ca. 1 Tag, um alle Unterlagen und Daten zusammenzutragen. Anschließend braucht der Steuerberater nochmal ca. 4 Wochen. Diese Aufwände sind mit wenig Unsicherheit behaftet. D.h. dringend wird für mich die jährliche Steuererklärung vielleicht 5 Wochen vor Abgabetermin.

Zu Beispiel 2: Wie groß ist der Aufwand für das Angebot? Vielleicht dauert es nur 1 Stunde, vielleicht dauert es aber auch 1 Woche, um alles durchgerechnet und formuliert zu haben. Wie unwägbar ist der Aufwand? Statt 1 Stunde könnten es auch 2 sein? Statt 1 Woche auch 3? Wenn der Versand per Email quasi in Nullzeit erfolgt, dann wird das Angebot 2 Stunden bzw. 3 Wochen vor Abgabetermin dringend.

Zu Beispiel 3: Wie groß ist der Aufwand, die Geldreserve wieder aufzustocken bis sie das nächste Mal in Anspruch genommen werden muss? Vielleicht geschieht das durch eine absehbare Zahlung eines Kunden in der nächsten Woche, vielleicht braucht es aber auch Wochen und Monate. Im ersten Fall tritt Dringlichkeit vielleicht gar nicht ein, weil die Entwicklung des Reservebestands bis nächste Woche nicht bei Null angekommen sein wird. Im zweiten Fall ist die Aufstockung eher kontinuierlich dringend, solange die Reserve unterhalb einer Sollmarke liegt.

Das Wichtige verdringlichen

Mit der Zeit wird alles Wichtige dringend. Wenn wir das aber passiv zulassen, dann reagieren wir nur noch. Dann sind wir nicht mehr Herr im eigenen Haus, sondern werden „Spontanbränden“ zur ewigen Feuerwehraktionen gezwungen.

So lässt sich ein Unternehmen führen – sogar recht lange, wie ich immer wieder feststellen muss. Aber macht das Spaß? Ist das ökonomisch? Das bezweifle ich.

Ich ziehe Agieren dem Reagieren vor. Ich ziehe fließende ruhige Abarbeitung dem Hinterherhecheln vor.

Dafür ist es unabdingbar, das Wichtige nicht aus den Augen zu lassen. Sonst erschreckt es uns irgendwann.

Wenn nun aber anscheinend nur das Dringende getan wird, muss das Wichtige von vornherein auch dringend sein. Wir müssen es also bewusst und angemessen verdringlichen. Wie kann das geschehen?

Beobachtung

Am Anfang steht für mich, sich des Wichtigen überhaupt erst einmal bewusst zu werden – und dann das Wichtige zu beobachten. Wie entwickeln sich wichtige Metriken? Steigen oder fallen Mitarbeiterfähigkeit, Mitarbeitermotivation, Vertriebserfolg, Softwarequalität, Betreuungszufriedenheit usw.?

Daraus ergeben sich früher oder später wünschenswerte und existenzbedrohende Werte für die Metriken und auch Entwicklungskurven.

Planung

Wenn insbesondere die existenzbedrohenden Zustände und ihre Entwicklungskurven bekannt sind, dann plane ich konkrete Kompensationen ein, soweit das geht. Für die Steuererklärung trage ich einen Tag 5 Wochen vor dem Abgabetermin ein. Für die Angebotsabgabe blocke ich z.B. 4 Stunden ein oder zwei Tage vor Abgabetermin – sobald ich den kenne.

Auf diese Weise überrascht mich das Wichtige nicht, sondern ich kann ihm mit einem Blick in den Kalender immer ins Auge sehen. So kann ich andere Tätigkeiten danach ausrichten und das Wichtige läuft nicht Gefahr, unter den Tisch zu fallen.

Gewohnheit

Nicht alles Wichtige ist termingebunden oder in seiner Entwicklung länger vorher absehbar. Punktuelle Termine kann ich in den Kalender nicht eintragen. Deshalb muss ich aus der Behandlung des Wichtigen eine Gewohnheit machen.

Meine Geldreserve stocke ich regelmäßig jeden Monat mit einem bestimmten Betrag auf. Um meine Fakturierung kümmere ich mich regelmäßig einmal im Monat. Um meine Positionierung kümmere ich mich jeden Tag eine Stunde. Um das Lernen kümmere ich mich jede Woche 4 Stunden usw.

Hier löst nicht ein „Hau-ruck-Aufwand“ das Problem, sondern Kontinuität. Das Wichtige wird nicht on-demand angegangen, sondern ständig in mehr oder weniger kleinen Häppchen. Das Motto: “Stehter Tropfen hölt den Stein.”

Automatisation

Geplante und rhythmisierte Maßnahmen muss ich noch selbst übernehmen. Ein nächster Schritt ist die Übertragung des Wichtigen an einen Automaten. Der kann geplant, rhythmisch oder on-demand Zustände beobachten und kompensierende Maßnahmen durchführen. Ein Beispiel dafür ist der Dauerauftrag ans Finanzamt für die Einkommenssteuervorauszahlung. Aber auch die Garbage Collection einer Runtime gehört dazu: statt das Wichtige – Speicherverwaltung – dem “Zufall” (oder der mehr oder weniger entwickelten Fähigkeit von Entwicklern) zu überlassen, automatisiert die Runtime die Berücksichtigung dieses Aspekts.

Stakeholder

Wenn eine Automatisation nicht möglich ist, setze ich einen menschlichen Stakeholder ein, dessen (Haupt)Aufgabe das Wichtige ist. Sobald ich mehr mit Abarbeitung des Geplanten und des Kontinuierlichen und der Beobachtung des Wichtigen zu tun habe, als meine Arbeitszeit zulässt, sollte ich Teile des Wichtigen „outsourcen“.

Das gilt auch, wenn ich für das Wichtige unterschiedlich qualifiziert bin. Es mag genauso wichtig sein, eine neue Website aufzusetzen wie neue Kunden zu gewinnen. Aber ich bin besser qualifiziert, für mich Kunden zu finden, als meinen Website zu überarbeiten mit all den HTML5/CSS/JS-Feinheiten, die heute state-of-the-art sind.

Nach der Manifestation des Wichtigen im Kalender und im Rhythmus kommt also die Manifestation in Form einer Person. Damit bekommt das Wichtige zwei Beine, die immer wieder den Weg zu mir finden, um Input einzufordern. Das ist dann wiederum für mich wichtig und sollte ebenso geplant oder rhythmisiert werden.

Zusammenfassung

Wenn sich Dringendes immer wieder störend in unseren Arbeitsfluss mischt, läuft etwas falsch. Dann haben wir das Ruder aus der Hand gleiten lassen.

Unerwartet Dringendes gilt es mit aller Macht zurückzudrängen und zur Ausnahme zu machen. Stattdessen müssen wir versuchen, das Wichtige bewusst so zu konkretisieren, dass es sich wie Dringendes ausnimmt, geplantes Dringendes. So können wir auch erkennen, wenn es über unsere Kräfte geht. Dann müssen wir Hilfe suchen.

Es ist also nicht schlimm, wenn nur Dringendes erledigt wird. Wir dürfen uns davon nur nicht überraschen lassen. Umarmen wir also das Dringende. Machen wir uns seine Kraft zunutze.

Montag, 7. April 2014

Arbeitszeiteinteilung für Veränderung

Der Wunsch, irgendwie besser Software zu entwickeln, ist weit verbreitet. Irgendwas stört in jedem Projekt. Irgendwie hakt es in jedem Team. Viele leiden unter der Last von Legacy Code. Andere kämpfen mit Qualitätsproblemen oder unzuverlässiger Lieferung.

Zur Verbesserung der Situation lässt sich dann natürlich allerlei raten. Mehr Clean Code, konsequentere Agilität, bessere Infrastruktur, modernere Tools und Technologien usw. usf. bieten sich an. Die Wiese ist bunt und groß, von der man sich einen Strauß an Maßnahmen pflücken kann.

Der schönste Blumengruß kann jedoch keine Wirkung entfalten, wenn es an einer Vase fehlt. Dann freut sich der Empfänger – und weiß anschließend nicht recht, wohin damit.

Zunehmend scheint mir das der Fall zu sein. Organisationen kommen aus ihren Problemen nicht raus, weil es ihnen am Grundsätzlichsten fehlt, um überhaupt irgendwelche Maßnahmen umzusetzen.

Die Arbeitszeit ist nämlich gefüllt mit Tagesgeschäft, d.h. mit Dringendem, mit Zeugs, das einfach irgendwie weggeschafft werden muss.

image

Da ist kein Raum, um irgendetwas anderes noch unterzubringen. Da ist auch kein Raum für Fehler – jenseits derer, die ja ohnehin passieren.

Überall wird ohne Puffer gearbeitet. Die Arbeit fließt so wie Berufsverkehr zur Rush Hour: Es geht voran, aber langsam. Und wehe, es hakt irgendwo!

Platz für Neues gibt es in solcher Arbeitsweise nicht. Der vorhandene Zeitraum ist ja schon ausgefüllt.

Und so sitzt man da in seiner Misere. Es tut weh, man weiß, dass es anders sein sollte, man ist guten Willens – aber man sieht sich auch außerstande, Maßnahmen anzugehen und verlässlich umzusetzen.

Am schönsten wäre es, wenn mit Tips & Tricks alles besser würde. Nicht lange lernen oder umdenken, nur hier und da eine Kleinigkeit ändern – am besten durch Einsatz eines Tools – und schon wird aus einer verstopften Autobahn eine Rennstrecke.

Nun… dazu kann man nur sagen: dream on!

So funktioniert es nicht. Nirgends. Das bedeutet nicht, dass nicht hier und da Tips & Tricks bewirken können. Nur reichen Tips & Tricks nicht aus. Eine Organisation, die über längere Zeit Schmerzen spürt, leidet an etwas, das tiefer liegt.

Um diese tiefer liegende Ursache angehen zu können, ist mehr nötig, als hier und da kleine Tips & Tricks umzusetzen. Dafür braucht es Raum, zeitlichen Raum und womöglich sogar physischen Raum.

Das Minimum in dieser Hinsicht sieht für mich so aus:

image

Ja, ich glaube, weniger geht nicht. Und ich werde immer unwilliger, mit Organisationen zu arbeiten, die ihre Arbeit nicht so einteilen können.

  • Reflexion, 5% bzw. 2h/Woche: Ohne Reflexion gibt es keinen Weg. Reflexion bedeutet nämlich Innehalten, d.h. einen Punkt zu bestimmen, an dem man steht und von dem aus man betrachten kann, woher man gekommen ist und wo im Verhältnis zum Ziel man sich befindet. Gibt es Abweichungen, bietet die Reflexion Chance zur Kurskorrektur. Geradlinige Veränderung zum Besseren gibt es nicht. Verbesserung insbesondere chronischer Leiden ist kein ballistischer Flug; es kann keine Maßnahme “abgeschossen” werden, die nach einiger Zeit einfach ins Ziel trifft. Das gilt auf persönlicher wie organisatorischer Ebene. 2 Stunden Reflexion pro Woche sind für mich das Minimum, um insb. in expliziten Veränderungsprozessen, den Weg zu finden. Die können sich aus persönlicher Reflexion und Reflexion im Team zusammensetzen, z.B. jeder Einzelne pro Tag 15 Minuten und das Team einmal pro Woche 45 Minuten.
  • Lernen, 10% bzw. 4h/Woche: Methoden, Tools, Technologien, Konzepte sind ständig im Wandel. Wer glaubt, nebenbei durch gelegentliche Lektüre der c’t am Ball bleiben zu können, lebt in einer Illusion. Persönlicher Marktwert und die Fähigkeit von Teams nehmen ohne explizites und regelmäßiges fokussiertes Lernen ständig ab. Lernen passiert nicht nebenbei. Dafür braucht es einen speziellen Raum – und zwar innerhalb der Arbeitszeit. Mindestens 4 Stunden pro Woche scheinen mir das Minimum. Das kann ein Nachmittag sein oder zwei Mal 2 Stunden. Weniger Lernzeit en bloc jedoch bringt zu wenig Fokus. Was und wie gelernt wird, ist weniger wichtig, als dass gelernt wird. Lernen bedeutet: etwas anders machen als üblich, Spaß haben, Fehler erlauben. Es kann grundlegend gelernt werden, d.h. vom Inhalt her sehr frei, oder auch angewandt, d.h. schon mit Blick auf ein konkretes Problem. Organisationen, die im Wettbewerb stehen, können sich einen Verzicht auf kontinuierliches Lernen letztlich nicht erlauben. Wer nicht durch Lernen den state-of-the-art ständig exploriert, hat keinen “Wissenspuffer”, aus dem er Neues, Cooles, Begeisterndes schöpfen kann.
  • Strategisches, 12,5% bzw. 5h/Woche: Losgelassen frisst das Tagesgeschäft, d.h. das Dringende, das Plötzliche alle Arbeitszeit. Das darf aber nicht sein, denn das Tagesgeschäft ist nicht zukunftsorientiert. Es blick nur vor die Füße und zurück. Den Blick nach vorne stellt die Strategie dar. Sie definiert, was wichtig ist. Zu jeder Zeit gibt es in dieser Hinsicht auch nur ein Wichtigstes. Das gilt für jeden Einzelnen wie Organisationen. Ich nenne das den “Highlander”, weil es nur einen geben kann, einen wichtigsten Zielpunkt, auf den man zusteuert. Ist der erreicht, dann gibt es einen neuen usw. Was der Highlander-Zielpunkt ist, in welcher Entfernung er liegt… das ist einerlei. Gewiss ist jedoch, dass er nicht erreicht wird, wenn man sich ihm nicht konsequent Schritt für Schritt nähert. Das bedeutet für mich: an jedem Tag muss dem Highlander mindestens 1 Stunde gewidmet werden. Eine Stunde konzentrierte Arbeit für das wichtigste strategische Ziel sorgt dafür, dass die Verlässlichkeit extrem steigt.
  • Tagesgeschäft: Wenn Strategie, Lernen und Reflexion bedient sind, kann die restliche Arbeitszeit mit dem Tagesgeschäft gefüllt werden. Das gibt es und es wird bleiben. Aber es muss in seine Schranken verwiesen werden.

Es mag sich viel anhören, mehr als 25% der Arbeitszeit auf “so softes Zeugs” zu verwenden. Jahre der Beratungspraxis und Jahre der persönlichen Beobachtung meiner Selbstständigkeit haben mich jedoch zu der Einsicht gebracht: weniger geht nicht.

Weniger mag kurzfristig mal funktionieren. So wie man auch mal 100m sprinten kann und dabei das Atmen vergisst. Aber mittel- und langfristig ist weniger zu wenig. Wenig bedeutet Umherirren oder gar Stehenbleiben. Weniger erzeugt über kurz oder lang Schmerzen.

Das ist wie mit dem eigenen Körper: Nach einem strammen Spaziergang, ist es ok, die Beine hochzulegen. Aber wer 3 Wochen im Sessel verweilt, der entwickelt alle möglichen Probleme von Sehnenverkürzung über Muskelatrophie bis Dekubitus.

Natürlich stellt sich eine solche Arbeitszeiteinteilung nicht einfach so ein. Ein Poster auf dem Flur und eine markige Ansprache unter dem Motto “Wir wollen jetzt eine lernende Organisation werden!” sind nicht genug. Es reicht auch nicht, die Zeiträume für Reflexion, Lernen und Strategisches zuzugestehen. Das ist nur Förderung. Die ist notwendig, aber nicht hinreichend. Dazu muss Forderung kommen. Reflexion, Lernen und strategische Arbeit müssen eingefordert werden. Und das ist eine Aufgabe für das Management – sogar zunächst eine strategische.

Montag, 10. März 2014

Attrappen gestütztes Nachdenken

Wie viel Design vor dem Codieren darf es denn sein? Diese Frage erhitzt immer wieder die Gemüter. Neulich auch das von Robert C. Martin. Der reagierte nämlich sehr barsch auf einen Blogartikel von Justin Searl.

Martin sieht nun einen Unterschied in der Notwendigkeit zu entwerfen zwischen größeren Strukturen und kleineren. Für die einen sollte man explizit entwerfen, für die anderen sich durch TDD treiben lassen. Ich allerdings erlaube mir anderer Meinung zu sein. Für mich gibt es keine wie von Martin beschriebene Diskontinuität. Vielmehr sehe ich Software als selbstähnliche Struktur, die deshalb auf allen Ebenen auch ähnlich behandelt werden will. Ausführlicher erkläre ich das ein einem englischen Blogartikel.

Damit sei das Thema erledigt – doch dann ließ mich der Artikel von Searl nicht recht los. Der beschreibt nämlich einen TDD-Ansatz, den Searl für mindestens didaktisch günstiger hält als “den traditionellen”.

Schon beim ersten Lesen flog mich da eine Ähnlichkeit zu Flow-Design an, doch ich konnte sie noch nicht recht greifen. Als mir jedoch die Mock-Frameworks TypeMock Isolator und JustMock einfielen, habe ich mich darangesetzt, und Searls Vorschlag ausprobiert. Das Ergebnis hat mir sehr gefallen.

Schon lange setze ich keine Mock-Frameworks mehr ein, weil die Zahl der Attrappen zum Test meiner Flow-Designs klein ist. Für noch ausgefeiltere Mock-Frameworks wie die beiden hatte ich deshalb schon gar keinen Bedarf. Doch jetzt finde ich sie sehr nützlich. Lange hat das Profiler-gestützte Mocking auf einen Einsatzzweck bei mir gewartet, nun ist er da: mit JustMock kann ich Flow-Designs schneller in Code übersetzen – und das top-down.

Wie ich mir das denke, habe ich in einem längeren englischen Blogartikel beschrieben. Der ist als Dialog abgefasst, weil er eine Herangehensweise an TDD beschreibt – wie weiland Martin es getan hat.

image

Den Dialog zu schreiben, hat Spaß gemacht. Das war mal ein ganz anderes Format als sonst. Doch, ja, ich gebe zu, er ist ein bisschen lang und gewunden geworden. Jedenfalls für den normalen Leser im Web, der schnell, schnell Informationen sammeln will.

Deshalb habe ich das Vorgehen in einem englischen Folgeartikel nochmal systematischer beschrieben. “Informed TDD” habe ich diese Herangehensweise genannt, weil hier TDD nicht “blind” aufgrund von Testfällen betrieben wird, sondern geleitet durch ein entwerfendes Nachdenken.

image

Ich verstehe, wenn manchem der Entwurf am Flipchart zu theoretisch ist. Zwar halte ich das für eine Gefühl, das sich mit etwas Übung überkommen lässt – doch erstmal ist es halt so. Mit “Informed TDD” kann hier jedoch schneller abgeholfen werden: Das Nachdenken kann kürzer ausfallen, weil es das Problem zunächst weniger tief durchdringen muss. Schneller kann man zur Tastatur greifen und schonmal Code schreiben, der das Nachdenken verifiziert. Schrittweise werden die durch “hartes TDD” zu lösenden Probleme auf diese Weise kleiner.

Attrappen stützen also das Nachdenken. Und das ganz modern ohne spezielle Vorkehrungen für eine Injektion von Funktionalität.