Follow my new blog

Dienstag, 13. Juli 2010

Testnähe aus der Distanz betrachtet

Die Diskussion um den besten Platz für Tests reißt nicht ab. Nach meiner Gegenüberstellung zweier Testplatzierungsstile hat Stefan nachgelegt und nun Ilker gekontert. Die WM ist vorbei, der Testball aber noch im Spiel… :-)

Was für ein Spiel ist das aber? Ist es ein Nullsummenspiel? Und worum dreht es sich? Die erste Frage ist, was “nah am zu testenden Code” bedeutet. die zweite Frage, ob Nähe das wichtigste oder gar einzige Kriterium für die Platzierung von Testcode ist.

Nah und fern

Wie nah ist nah? Ist “nah am Code” nur dies? Test und System-under-Test (SUT) liegen im selben Projekt.

image

Oder wäre es sogar so noch besser? Der Test ist dem SUT visuell untergeordnet, um den Blick auf die Hauptfunktionalität nicht zu verstellen:

image

Oder ist Nähe noch gegeben, wenn Tests in eigenen Unterverzeichnissen stehen?

image

Oder darf ich mit Recht behaupten, dass Tests platziert in einem eigenen Projekt noch nah sein können?

image

Hm… verwirrend diese Optionen. Oder sind sie gar nicht so verschieden, denn wie sieht es während der Arbeit an SUT und Tests in Visual Studio aus? Ist aus diesen Bildern die Platzierung der Tests abzulesen?

image 

image

Ich sehe da keinen Unterschied, obwohl die Tests sehr unterschiedlich platziert sind. Für die Arbeit am Code, also den ständigen Wechsel zwischen Test und SUT und Test und SUT, scheint es mir unbedeutend zu sein, ob die Tests als “near spec” im Projekt des SUT liegen oder in einem anderen Projekt. Solange sie in derselben Solution zu finden sind, können Tests und SUT ganz einfach so dargestellt werden.

Wer es noch verwegener mag und einen großen Bildschirm hat, der legt sich Tests und SUT sogar nebeneinander. Solche Darstellung überwindet jede Distanz. Programmieren wird da zur Kuschelstunde ;-)

image

Angesichts dessen würde ich sagen, dass es während der Arbeit an Tests und SUT einerlei ist, ob die Tests im SUT-Projekt liegen oder in verschiedenen. Solange sie sich in derselben Projektmappe befinden, ist der Wechsel zwischen beiden einfach möglich. Im Editor kann man sie immer in die Nähe rücken. Dasselbe gilt für Testdaten.

Kohäsion

Für die Arbeitsgeschwindigkeit an Tests und SUT sollte es keinen Unterschied machen, in welchem Projekt Tests platziert sind. Wie sieht es aber mit der Verständlichkeit aus? Ist Code besser zu verstehen, wenn Tests inkl. Testdaten und SUT in einem Projekt liegen? Ist nicht die Kohäsion zwischen Tests und SUT höher als die zwischen zwei unterschiedlichen SUTs? Müssten daher nicht Tests sogar eher in einem Projekt zusammen mit ihrem SUT liegen als zwei verschiedene SUTs?

Hier ein Blick in die Sourcen von RavenDB, der dokumentenorientierten NoSql-Datenbank von Ayende Rahien:

 image

Die Tests für den Client liegen in einem eigenen Projekt. Ob sie sich nur auf das markierte SUT-Projekt beziehen oder auch die anderen Client-Projekte, ist nicht ersichtlich. Das widerspricht der hohen Kohäsion von Test und SUT, würde ich sagen. Die Zusammenhänge zwischen beiden zu erkennen, ist schwierig.

Wer den Code grundsätzlich so strukturiert, d.h. viele Projekte in einer Projektmappe führt, der beklagt zurecht, dass die natürliche Kohäsion durch getrennte Projekte für Tests und SUT schwer auszudrücken ist.

Wie gesagt, dem Wechsel zwischen SUT und Tests tut das keinen Abbruch. Doch die Übersichtlichkeit leidet zunächst.

Was aber, wenn Software besser strukturiert ist? Wenn ihr ein Plan zugrunde liegt, der auch noch umgesetzt wird? Was wenn Plan und Code gar übereinstimmen? Hier ein Beispiel aus dem CCD Praktikum:

image

Das ist der Plan für ein Feature eines Softwaresystems für Kinos, das wir im Praktikum begonnen haben. Der Plan zeigt die Prozessschritte für ein Feature. Er ist als EBC-Schaltplan ausgelegt. Die Kästen werden in Klassen übersetzt. Die Pfeile in Event-Eventhandler-Verbindungen. Darüber hinaus gibt es aber auch noch Zusammenfassungen zu Komponenten. Die habe ich farblich hervorgehoben. Sie werden in Projekte übersetzt.

Im Repository sieht das dann so aus:

image

Die Komponenten finden sich dort als Projektmappen in eigenen Verzeichnissen wieder. (Wer mag, kann die natürlich auch wieder in Unterverzeichnissen gruppieren.)

Und innerhalb der Komponenten sind jeweils mindestens zwei Projekte zu finden, eines für das SUT sowie eines für dessen Tests:

image

Die hohe Kohäsion zwischen Tests und SUT findet dadurch klaren Ausdruck, würde ich sagen. Wer Tests zu einem SUT sucht, weiß genau, wo er sie findet.

Voraussetzung dafür ist natürlich der explizite Wille zur Architektur. Wo es den nicht gibt oder wo der nicht walten kann, weil der Brownfield-Matsch so tief ist… da mag es tatsächlich angezeigt sein, Tests und SUT im selben Projekt zu pflegen. Doch man sei sich bewusst, was dafür der Grund ist. Tests und SUT im selben Projekt ist dann ein Symptom der Grundproblems “Brownfield”. Tests und SUT im selben Projekt sind aus meiner Sicht daher kein Ziel, sondern nur eine Übergangslösung.

Trennung

Worin sich alle Diskutanten auch einig sind, das ist die Notwendigkeit der Trennung von Tests und SUT bei der Auslieferung. Tests und ihre Artefakte sollen nicht zum Kunden.

Wenn Tests und SUT in verschiedenen Projekten liegen, ist diese Trennung trivial. Testsprojekte haben ein anderes Output-Verzeichnis als SUT-Projekte, so dass Visual Studio beim Bau einer Solution automatisch die Trennung vornimmt. Im SUT-Output-Verzeichnis kommt immer nur das an, was auslieferungsrelevant ist.

Anders wenn Tests und SUT zusammen in einem Projekt stehen. Dann muss der Buildprozess explizit angewiesen werden, Tests und Testartefakte auszufiltern. Das mag eine Zeile Scriptcode sein oder viele. Egal. Wer den Buildprozess aufsetzt, muss daran denken. Und Entwickler müssen womöglich auch daran denken und während der Entwicklung Konventionen einhalten, die das ermöglichen.

So hoch die Kohäsion zwischen Tests und SUT prinzipiell sein mag – bei der Auslieferung hört sich dann doch auf.

Wenn es aufgrund von monolithischem Code nicht anders geht, die Kohäsion während der Entwicklung auszudrücken als durch Zusammenlegung von Tests und SUT in einem Projekt, dann sei es so und man filtere am Ende beim Build die Tests heraus. Aber, bitte, bitte, man verkaufe mir das nicht als Tugend. Zusätzlicher Aufwand ist zusätzlich fehleranfällig. Wenn ich ihn nicht treiben muss, dann möchte ich das auch nicht.

Eine saubere, angemessene Planung mit klarer Übersetzungsregel schenkt mir also nicht nur Evolvierbarkeit, sondern auch übersichtliche Codeverhältnisse und weniger Aufwand für den Buildprozess. Dann bin ich für saubere, angemesse Planung, würd ich sagen. (Die nicht zu verwechseln ist mit BDUF.)

Fazit

Tests im selben Projekt wie ihr SUT? Ist einzig das zeitgemäß? Ich würde sagen, wir sollten nicht nach Geschmack und Mode und Zeitgeist entscheiden. Professionelle Arbeit braucht Werte und Prinzipien. Um welche geht es hier?

Produktionseffizienz: Tests im selben Projekt sollen die Arbeit beschleunigen. Der Wechsel zwischen beiden soll leichter fallen. Wie oben gezeigt, glaube ich daran jedoch nicht. Visual Studio macht es leicht, für die Arbeit an Tests und SUT Nähe im Editor herzustellen. Und mit einem Tool wie dotCover wird es noch einfacher.

image

Als Beispiel die Open Source Software Lounge Repository. Sie ist komponentenorientiert entwickelt, d.h. für jede Komponente gibt es auch eine Werkbank bestehend aus Tests und SUT in je verschiedenen Projekten.

image

Allerdings bin ich bei der Codeorganisation einen Kompromiss eingegangen und habe alle Projekte in einer Projektmappe versammelt. Damit wollte ich es dem unbedarften Open Source Freund ein wenig einfacher machen, in die Quellen einzusteigen.

Ich finde das übersichtlich; viel übersichtlicher als die RavenDB Sourcen trotz Multi-Projekt Solution. Die Tests liegen nahe dem SUT, sie sind damit “near specs”. Aber gerade geht es ja um Produktionseffizienz. Die ist nicht nur hoch, weil ich Tests und SUT side-by-side im Editor liegen können (s.o.), sondern auch, weil dotCover mir erlaubt, aus dem SUT zum Test zu springen:

image

Die Liste auf der rechten Seite zeigt die Tests, die eine bestimmte SUT-Zeile abdecken. Damit muss ich gar nicht mehr wissen, wo in einer Projektmappe Tests überhaupt stehen. Ich lasse schlicht alle Tests mit dotCover ausführen, bekomme einen Eindruck vom Nutzen der Tests aufgrund ihrer Codeabdeckung – und kann dann aus den SUT-Zeilen, an denen ich gerade arbeite, zu relevanten Tests springen. Im selben Projekt oder in anderen. Wenn das nicht effizient ist.

Ebenfalls effizient ist, dass bei Trennung von Tests und SUT kein weiterer Aufwand für die Trennung beider Anteile während der Produktion zu treiben ist. Nicht anfallender Aufwand ist ganz eindeutig der kleinste mögliche Aufwand.

Übersichtlichkeit: Der nächste für die Kolokation von Tests und SUT reklamierte Wert ist die Übersichtlichkeit. Es sei übersichtlicher, wenn beide in einem Projekt lägen. Wie gesagt, das kann ich glauben, wenn es denn nicht anders geht. Wenn die Verteilung auf zwei Projekte ihrer natürlichen Kohäsion zuwiderläuft, weil sie dann sehr weit auseinander stünden in einer Projektmappe, dann mag die Kolokation einen Vorteil haben.

Der Umkehrschluss ist jedoch aus meiner Sicht falsch: Weil Zusammenlegung im Matschfeld einen gewissen Vorteil haben kann, weil damit ein grundlegendes Problem pragmatisch kurzfristig kaschiert wird, deshalb sollten Tests und SUT möglichst immer zusammengelegt werden. Nein, so würde der Bock zum Gärtner.

Darüber hinaus sollte Übersichtlichkeit aber noch weiter gefasst werden. Die zu einem SUT gehörenden Tests leicht finden können, ist eine Sache. Wie stehts aber mit der Identifikation von SUTs? Wie steht es mit Verantwortlichkeiten der Software im Allgemeinen auf unterschiedlichen Abstraktionsebenen?

Übersichtlichkeit entsteht nicht nur durch Zusammenlegung, sondern auch durch Trennung. Mir scheint, dass dieses Prinzip schnell übergangen wird, wenn man im Kolokationsflow ist. Denn wo Tests und SUT zusammengeschnürt werden sollen, dann halte ich die Tendenz für hoch, auch anderes zusammen zu schnüren. Und am Ende entsteht bzw. wird erhalten der Monolith, das Softwaresystem mit hoher Entropie, das Brownfield.

Statt Tests als Anlass zu begreifen, zumindest mal einen Concern aus dem großen Brownfield herausziehen zu können, trägt die Kolokation vielmehr zum Erhalt des status-quo bei. Schade.

Mein persönliches Fazit der Diskussion: Zeitgeist und Geschmack bringen uns nicht weiter. Meinungen sollten auf Prinzipien verweisen. Sie sollten zeigen, wie und warum und wann diese oder jene durch eine Praktik besser oder schlechter umgesetzt werden.

Bei trivialem Code mag es daher ok sein, Tests und SUT zusammenzufassen. Eine Code Kata könnte dazu gehören – wenn man nicht gerade üben möchte, eine andere Codeorganisation einzuhalten.

Jenseits des trivialen Codes bezweifle ich jedoch, dass Tests und SUT im selben Projekt der Produktionseffizienz und Übersichtlichkeit wirklich dienen. Sie sind mir eher Symptom für ein Wurzelproblem und Bequemlichkeitsmaßnahme. Mehr als eine Übergangslösung aus der Not geboren sehe ich in ihnen nicht. (Mann, oh, mann, wie störrisch und uneinsichtig ist das denn eigentlich ;-) Aber es hilft nix: “Hier stehe ich, ich kann nicht anders.” Für die Zukunft gelobe ich jedoch, den Kontext besser zu berücksichtigen. Bei einer Code Kata könnte ich mal von dieser “Prinzipienreiterei” abesehen ;-)

Sonntag, 11. Juli 2010

Mit vielen Gehirnen entwirft man besser [OOP 2010]

image Was macht einen erfahrenen Entwickler aus? Dazu habe ich grad hier etwas gelesen und bin beim “Mid-Level Developer” (beim “Mittelmäßigen” möcht ich da mal nich rauslesen ;-) auf diesen Satz gestoßen:

“Can work from user stories”

Was bedeutet das? Ich habe herausgelesen: “Der mid-level Developer kann das, was er am Quellcode zu tun hat, selbstständig aus User Stories ableiten.”

Stimmen Sie mit mir in dieser Interpretation überein? Wenn ja, dann hier zur Begründung, warum ich darüber den Kopf geschüttelt habe.

Welcher Ansatz von Softwareentwicklung steht dahinter, wenn Entwickler ihre Arbeit am Quellcode selbst aus User Stories ableiten? Ich stelle mir das so vor:

Es gibt eine Besprechung, in der User Stories vorgestellt werden. Das Team klärt sein Verständnis der Anforderungen, die darin stecken. Dann wird vielleicht der Aufwand geschätzt. Dann wird geklärt, welche User Stories in Angriff genommen werden sollen. Und dann melden sich Entwickler, die einzelne User Stories umsetzen wollen. Sie arbeiten im Sinne eines Durchstichs, also einer allein (oder vielleicht zwei im Pair) realisieren die User Story.

Ich behaupte nicht, dass der Autor des Blogpostings so arbeitet. Ich behaupte auch nicht, dass er meint, ein mid-level Developer solle so arbeiten. Die obige Formulierung jedoch suggeriert mir so ein Vorgehen. Und das ist so weit weg von dem, wie ich meine, dass Software entwickelt werden sollte, dass ich einfach mal einhake.

image In der letzten Woche habe ich mit Stefan Lieser das Clean Code Developer Praktikum durchgeführt. Fünf Tage lang haben wir darin mit fünf Entwicklern Projekte angepackt. Die kleinsten waren Code Katas und in 2-3 Stunden zu realisieren; das größte dauerte jedoch 2 Tage und ist noch nicht abgeschlossen.

Und wenn mir in den Tagen eines klar geworden ist, dann dies:

Kein Entwickler sollte allein von User Stories ausgehend arbeiten.

Wir haben jedes Projekt mit der Erarbeitung eines gemeinsamen Verständnisses der Anforderungen begonnen. Anschließend haben wir gemeinsam den Lösungsansatz erarbeitet. Viele Gehirne haben also die Anfordeurngen hinterfragt, viele Gehirne haben sich kreativ in den Entwurf eingebracht. Das war für die Projekte unheimlich hilfreich.

Nicht nur wurde dadurch eine gemeinsame Sprache als Basis für den vertrauensvollen Umgang mit der Problemdomäne im Team herausgearbeitet. Nein, alle haben auch dazu beigetragen, dass der Entwurf unter keinen blinden Flecken leidet. Und alle haben einen Überblick über die Gesamtanwendung bekommen.

image Gerade die konzentrierte gemeinsame Entwurfsphase war für mich immer tief befriedigend. Sie hat mir das Vertrauen gegeben, dass wir alle an einem Strang ziehen. Jeder hat sein Bestes gegeben, um einen angemessenen und realistischen Lösungsansatz zu entwickeln.

Das war Team Buildung und Software Design in einem. Ein effizienter und effektiver Prozess – der darüber hinaus auch noch Spaß gemacht hat. Keine Prinzipienreiterrei, sondern kreativer Fluss der Ideen im Rahmen des Clean Code Developer Wertesystems.

Aus meiner Sicht brauchen User Stories daher immer viele Entwickler und nicht einen. Ob der eine allein mit User Stories umgehen kann, ist mir recht egal. Wichtiger ist, ob ein Entwickler sich im Team in den Umgang mit User Stories einbringen kann, ob er einen Beitrag zum Verständnis und zur Planung der Umsetzung leisten kann.

Das hat denn für mich auch weniger mit Domänenwissen oder technischer Erfahrung zu tun, als vielmehr mit Softskills. Wie neugierig ist ein Entwickler? Wie “schnell im Kopf” ist sie? Ist sein Denken flexibel? Ist sie offen für Neues? Kann er querdenken? Wie geht sie mit anderen Teammitgliedern im Verständnis- und Entwurfsprozess um? Welche Erfahrung hat er mit dem Prinzipien- und Praktikenrahmen von Clean Code Developer?

Was das Erfahrungsniveau von Entwicklern definiert, weiß ich nicht so genau. Wie lange ist einer Junior Developer, ab wann ist einer Senior Developer? Mit einem bin ich mir aber sicher: Dass Softwareentwicklung jenseits des Trivialen ein Prozess ist, der entscheidend durch Phasen der Gemeinsamkeit geprägt ist.

Das reine Codieren darf gern im stillen Kämmerlein allein oder zu zweit geschehen. Es ist eine eher umsetzende, ausführende Tätigkeit. Klar, dabei ist auch Kreativität gefragt, aber die kann keinen großen Schaden mehr anrichten ;-) Denn sie findet in einem Rahmen und auf einem Fundament statt.

Und dieses Fundament, dieser Rahmen, die sind das Ergebnis gemeinschaftlichen Denkens. Da sind viele Gehirne gefragt.

Dienstag, 29. Juni 2010

Zeig mir deinen Code und ich nenn dir deinen Dojo-Stil

image Die Coding-Dojo-Welt hat sich geteilt. Es gibt nun den münchener Latifa-Stil von Ilker. Und es gibt den Schwarm-Stil von Stefan Lieser und mir. Bei der Teilung hat es ein wenig gerumpelt in der Community – aber nun sollten wir in friedlicher Koexistenz coden können. Die Welt ist halt bunt.

Den einen wahren, kanonischen Coding-Dojo-Stil gibt es nicht. Es gab und gibt nur Interpretationen dessen, was Leute wie z.B. Robert C. Martin mal gezeigt haben. Einzig in der Praktik des TDD sind sich die Dojo einig – und natürlich darin, dass Code geschrieben werden soll.

Über den Prozess, wie zu diesem Code im Dojo gekommen werden sollte, ist schon geschrieben worden. Das ist es, worin sich Latifa- und Schwarm-Stil unterscheiden. Und das macht natürlich einen Unterschied im Lernen der Teilnehmer.

Aber welchen Einfluss hat das auf das Produkt eines Dojos? Merkt man es dem Code an, ob er nach diesem oder jenem Stil entwickelt wurde? Ich habe mal versucht, das herauszufinden.

Für die Kata FizzBuzz habe ich versucht, mich in den Latifa-Stil hinein zu versetzen. Ich hoffe, das Ergebnis ist nicht zu sehr gefärbt von irgendwelchen Missverständnissen oder Voreingenommenheiten.

Anschließend habe ich den Code nach Schwarm-Stil Manier nochmal entwickelt.

FizzBuzz à la Latifa

Gerade nach der Erfahrung des letzten Coding Dojo zum dotnetpro.powerday bin ich mir sicher, dass ein Latifa-Dojo die grundsätzliche Codestruktur so aufgesetzt hätte:

image

Implementation und Test sind in einem Projekt zusammengefasst. Begründung: Mehr braucht es nicht. Das Beispiel ist so klein, dass alles andere Overkill wäre.

Von der Implementation nehme ich an, dass sie im Wesentlichen so aussehen würde:

public class FizzBuzzer
{
    public List<string> Generate()
    {
        var numbers = new List<string>();
        for (int i = 1; i <= 100; i++)
        {
            if (IsFizz(i) && IsBuzz(i))
                numbers.Add("fizzbuzz");
            else if (IsFizz(i))
                numbers.Add("fizz");
            else if (IsBuzz(i))
                numbers.Add("buzz");
            else
                numbers.Add(i.ToString());
        }
        return numbers;
    }

    private bool IsBuzz(int i)
    {
        return i % 5 == 0;
    }

    private bool IsFizz(int i)
    {
        return i % 3 == 0;
    }
}

Die Aufgabe ist klein. Hexenwerk ist nicht nötig. Alles geradlinig implementiert. Die Funktionen IsFizz() und IsBuzz() sind bei einer Refaktorisierung herausgezogen worden.

Exemplarisch hier auch noch ein Ausschnitt aus den Tests:

[TestFixture]
public class Test_FizzBuzzer
{
    [Test]
    public void Check_numbers()
    {
        var sut = new FizzBuzzer();

        var numbers = sut.Generate();

        Assert.AreEqual("1", numbers[0]);
        Assert.AreEqual("91", numbers[90]);
    }

    [Test]
    public void Check_fizz()
    {
        var sut = new FizzBuzzer();

        var numbers = sut.Generate();

        Assert.AreEqual("fizz", numbers[2]);
        Assert.AreEqual("fizz", numbers[98]);
    }
   …

Sie setzen alle beim FizzBuzz-API an – öffentliche Methode Generate() der FizzBuzzer-Klasse. Alle Tests sind Black Box Tests.

So, wie ich bisher die Latifa-Dojos erfahren habe, glaube ich nicht, dass weitere Refaktorisierungen vorgenommen worden wären. Ich glaube auch nicht, dass andere Datenstrukturen gewählt worden wären.

Und warum auch? Läuft doch.

FizzBuzz à la Schwarm

Nach solcher (visionierter) Vorlage eines Latifa-Dojos stellt sich die Frage, inwiefern eine Lösung überhaupt anders aussehen kann. Das Problem ist ja trivial. Kann es da überhaupt zwei Meinungen geben?

Ja, es gibt Alternativen. Der Schwarm-Stil unterscheidet sich also nicht nur im Prozess vom Latifa-Stil, sondern auch in seinem Anspruch an die Lösungsformulierung. Die beginnt bei der Codeorganisation:

image

Zwei Projekte, statt einem. Denn beim Schwarm legen wir Wert nicht nur auf TDD und Funktionalität, sondern auch auf Klarheit in der Form. Verständlichkeit ist uns wichtig. Separation of Concerns (SoC) gilt nicht nur innerhalb von Code, sondern auch für seine Form. Deshalb sind für uns Tests und Implementation immer getrennt. Der Schwarm bemüht sich, möglichst viele Clean Code Developer Bausteine zu berücksichtigen.

An der groben Codeorganisation ist aber noch mehr als eine SoC abzulesen. Das Testprojekt besteht aus drei Klassen. Die spiegeln wider, dass vor dem Coden über den Lösungsansatz nachgedacht wurde. Es hat eine kurze Kreativphase gegeben, in der erkannt wurde, dass die Lösung ein Prozess ist, der aus zwei Phasen besteht:

  1. Zahlengenerierung
  2. Zahlenübersetzung (Mapping).

Um diese Erkenntnis im Code festzuhalten, habe von vornherein für beide Phasen Methoden im Code vorgesehen. Und deshalb konnte ich mich auch entscheiden, welche ich davon zuerst nach TDD implementiere. Ich habe mich für die Zahlenübersetzung entschieden. Sie ist ja auch der Kern des FizzBuzz-Problems.

public class FizzBuzzer
{
    internal static string MapNumber(int number)
    {
        if (IsFizz(number) && IsBuzz(number)) return "fizzbuzz";
        if (IsFizz(number)) return "fizz";
        if (IsBuzz(number)) return "buzz";

        return number.ToString();
    }

    private static bool IsBuzz(int number)
    {
        return number % 5 == 0;
    }

    private static bool IsFizz(int number)
    {
        return number % 3 == 0;
    }

Natürlich habe ich die Tests jeweils vorher geschrieben:

[TestFixture]
public class Test_MapNumber
{
    [Test]
    public void Map_straight_number()
    {
        Assert.AreEqual("1", FizzBuzzer.MapNumber(1));
        Assert.AreEqual("2", FizzBuzzer.MapNumber(2));
        Assert.AreEqual("4", FizzBuzzer.MapNumber(4));
        Assert.AreEqual("98", FizzBuzzer.MapNumber(98));
    }

    [Test]
    public void Map_fizz_number()
    {
        Assert.AreEqual("fizz", FizzBuzzer.MapNumber(3));
        Assert.AreEqual("fizz", FizzBuzzer.MapNumber(6));
        Assert.AreEqual("fizz", FizzBuzzer.MapNumber(99));
    }

Von den Testfällen her unterscheiden die sich eigentlich nicht vom Latifa-Stil. Aber betonenswert anders ist, dass ich sofort mit dem Kern des Problems anfangen konnte, weil ich wusste, dass es dafür eine Funktionseinheit gibt. Und die Tests sind fokussierter, weil sie nur die Übersetzung testen und nicht immer auch noch die Zahlengenerierung berücksichtigen müssen. Schließlich ist der Code in der MapNumber()-Methode auch noch simpler als der Übersetzungscode beim Latifa-Stil, weil er weniger tief schachtelt (keine else-Zweige).

image Hätte der Latifa-Stil mit konsequentem TDD auch dahin kommen können? Klar. Aber die Latifa-Dojo-Erfahrung zeigt, dass das nicht passiert. Da es im Latifa-Stil kein “offizielles” Nachdenken über den Lösungsansatz gibt, gibt es auch keine Gewissheit, dass das demokratische Voranschreiten so tief ins Refactoring einsteigt, wo es doch viel spannender ist, überhaupt eine lauffähige Lösung zu produzieren.

Nach Implementation des Mappings habe ich die Zahlenerzeugung implementiert. Die ist natürlich trivial. Dem Schwarm-Stil ist das jedoch egal. Wenn in der Kreativphase ein Lösungsansatz erarbeitet wurde, der die Zahlengenerierung ausweist, dann wird sie in einer expliziten Funktionseinheit implementiert. Das entspricht dem Single Responsibility Principle (SRP).

internal static IEnumerable<int> NumberGenerator(int from, int to)
{
    for (var i = from; i <= to; i++)
        yield return i;
}

Die Zahlenerzeugung ist kein Bestandteil des API. Deshalb erfolgt sie in einer internen Methode.

Beim Testen ist zu sehen, dass auch der Schwarm-Stil pragmatisch vorgeht. Ich habe nur einen Test geschrieben:

[TestFixture]
public class Test_NumberGenerator
{
    [Test]
    public void Numbers_1_to_3()
    {
        var numbers = FizzBuzzer.NumberGenerator(1, 3);
        Assert.AreEqual(new[]{1,2,3}, numbers.ToArray());
    }
}

Im Sinne eines universellen Zahlengenerators ist das natürlich zuwenig. Wie würde der z.B. auf Zahlengrenzen < 0 reagieren? Wie würde er reagieren, wenn die erste Zahl größer als die zweite ist? Eine Beschränkung auf den problemrelevanten Happy Day Fall ist auch für den Schwarm-Stil ok.

Die Schritte des Lösungsansatzes müssen am Ende natürlich noch zusammengezogen werden. Das ist die Aufgabe der API-Methode:

public IEnumerable<string> Generate()
{
    return NumberGenerator(1, 100).Select(MapNumber);
}

Im Vergleich zur Latifa-Lösung folgt sie sofort dem Single Level of Abstraction (SLA) Prinzip. Die Lösung wird auf hohem, einheitlichem Abstraktionsniveau beschrieben. Und die Phasenfolge ist klar zu erkennen. Schwer zu verstehende Schachtelung ist nicht nötig.

Da die Einzelfunktionalitäten schon getestet sind, ist für die Integration nur noch ein Integrationstest nötig:

[TestFixture]
public class Integrationtest
{
    [Test]
    public void Check_number_generation_and_mapping()
    {
        var sut = new FizzBuzzer();
        Assert.AreEqual(
            new[] { "1", "2", "fizz" },
            sut.Generate().ToArray().Take(15));
    }
}

Der Test kann so kurz ausfallen, weil lediglich geprüft werden muss, ob die Funktionseinheiten überhaupt korrekt zusammenspielen.

Fazit

Wenn ich die typischen Vorgehensweisen von Latifa- und Schwarm-Stil hier halbwegs wirklichkeitstreu wiedergegeben habe, dann führen sie zu unterschiedlichem Code. Ob das eine Ergebnis besser oder schlechter ist, will ich nicht beurteilen. Mir war nur die Beantwortung der Frage wichtig, ob es überhaupt einen Unterschied gibt. Und wenn ja, was der ausdrückt.

Unterm Strich scheint mir hier Conway´s Law bestätigt: Der Code spiegelt Prozess und Organisation des Teams wider. Latifa setzt auf Demokratie, d.h. Gleichberechtigung und Gleichstellung, und hat darüber hinaus keinen Prozess jenseits TDD.

image Schwarm setzt auf einen klaren Prozess (Kreativphase gefolgt von Umsetzungsphase) und die Einhaltung von Prinzipien jenseits von TDD bei der Umsetzung.

Nun mag jeder (potenzielle) Teilnehmer an einem Dojo entscheiden, welchen Stil er/sie bevorzugt.

Samstag, 26. Juni 2010

Kollektiv intelligent codieren

Wenn ein einzelner Entwickler etwas codiert, dann hat das Ergebnis eine gewisse Qualität. Und wenn mehrere Entwickler zusammen etwas codieren, dann sollte das eine höhere Qualität haben. Oder?

Wie die sprießenden Coding Dojos zeigen, ist das nicht der Fall. Da mag der Spaß noch so groß sein, da mag die Motivation hoch fliegen – die Ergebnisse sind meist schlechter, als wenn ein einzelner Entwickler dasselbe probiert. Wenn nach 2 Stunden zwei 5zeilige Tests stehen und noch vielleicht 10 Zeilen Domänenlogik, ohne dass abzusehen wäre, wann die Aufgabe ganz gelöst sein wird, dann ist das ziemlich wenig.

Wie kann das aber sein, was geht schief beim Coding Dojo? Warum bleibt das Kollektiv der Dojo-Teilnehmer hinter Einzelleistungen verlässlich zurück? Oder sehe ich das ganz falsch und nichts geht schief? Ist das einzig schiefe der Sitz meiner Brille, durch die ich das Coding Dojo sehe?

Die anhaltende Diskussion (s. z.B. hier oder hier oder hier) über Sinn und Zweck von Coding Dojos lässt mich nun vermuten, dass die Diskutanten (mich eingeschlossen) aneinander vorbei reden.

Also setze ich heute mal meine übliche Brille erstmal ab und stecke mir eine Lupe aufs Auge.

Struktur von Dojo-Problemlösungen

Worum geht´s denn beim Dojo überhaupt? Es wird ein Szenario präsentiert, zu dem die Teilnehmer zusammen eine Lösung in Form von Code entwickeln sollen. Ob der Code durch einen Stellvertreter (Code Monkey) eingegeben wird, den die Gruppe “fernsteuert” oder ob Gruppenmitglieder reium den Code eingeben, ist an dieser Stelle nicht so wichtig. Ebenfalls noch nicht so wichtig ist, dass Dojos einen bestimmten Weg der Implementation favorisieren: das TDD.

Entscheidend ist die Art der Aufgabe: Übersetzung von Anforderungen in Code.

Diese Art der Aufgabe hat es nämlich in sich. Sie besteht aus zwei Phasen, die auch mehrfach durchlaufen werden können:

  • Phase 1: Kreativphase
  • Phase 2: Umsetzungsphase

Zwischen Anforderungen und “Produkt” steht mithin eine Barriere. Das ist der Entwurf des Produktes. Wie ein Produkt aussieht, ergibt sich nämlich nicht einfach so. Bevor man ein Produkt bauen kann, muss man eine Vorstellung davon haben, wie es aussehen soll.

Ein Bild vom Produkt, von der Lösung zu entwickeln, das ist nun ein kreativer Prozess. Aus den scheinbar oder tatsächlich möglichen Lösungen ist eine auszuwählen.

Ist die Auswahl getroffen, kann sie umgesetzt werden. Umsetzung erfordert also Klarheit in der Vorstellung, was umgesetzt werden soll.

Lösungsfindung und Umsetzung sind ganz verschiedene Tätigkeiten. Sie sind so verschieden, dass die Psychologie dafür zwei Arten des Denkens unterscheidet: divergentes Denken (oder auch laterales Denken) und konvergentes Denken.

image

Divergentes Denken ist in der Kreativphase nötig, konvergentes Denken in der Umsetzungsphase. Die Umsetzung ist also kein “no brainer”, sondern erfordert auch Denken. Denn selbst wenn die Lösungsstruktur grundsätzlich klar ist, bedarf die Umsetzung durchaus noch weiterer Entscheidungen. Umsetzung kann weit entfernt von “Malen nach Zahlen” sein. Umsetzung braucht Erfahrung und Kompetenz.

image

Sind Erfahrung und Kompetenz nicht aber auch für die Lösungsfindung (Kreativphase) wichtig? Interessanterweise sind Erfahrung und Kompetenz, also Expertentum, überbewertet, wenn es um kreative Lösungen geht. Lösungssuchende Gruppen sollten sich daher um Heterogenität bemühen; sonst schmoren Experten zu sehr in ihrem eigenen “Denksaft”. Der Horizont von homogenen Gruppen ist schlicht enger als der von heterogenen.

Fazit bis hierher: Wenn ein Coding Dojo daran interessiert ist, Anforderungen mit Code umzusetzen, dann ist es gut beraten, die zwei grundsätzlichen Phasen auf dem Weg dahin zu beachten. Ein Dojo muss sich also überlegen, wie es divergentes und konvergentes Denken herstellt.

Divergentes Denken in der Gruppe

Kollektive können gut divergent denken. Kollektive Intelligenz kann bei Problemen, die divergentes Denken erfordern, individueller Intelligenz relativ leicht überlegen sein. Ein Coding Dojo ist also gut aufgestellt, schöne Lösungsansätze für die gegebenen Anforderungen zu finden, da die Teilnehmergruppe gewöhnlich sehr heterogen ist.

Allerdings braucht es dafür eine Voraussetzung: das Dojo muss überhaupt eine Kreativphase durchlaufen. Nach Verständnis der Anforderungen muss es eine Phase geben, in der die kollektive Intelligenz divergent denkt. Ob diese Phase 3 Minuten oder 30 Minuten dauert, sei dahin gestellt. Das hängt ja auch vom Problem ab. Aber ohne eine solche Phase, d.h. einen Zeitraum im “Divergenzdenkmodus”, gibt es keinen Lösungsansatz.

Und wie sieht eine solche Kreativitätsphase aus? Was tun die Gruppenmitglieder da? Meine Vorstellung davon sieht so aus:

  • image Am Anfang der Kreativphase steht eine Stillarbeitsperiode. Jeder überlegt für sich, wie er/sie die Lösung gestalten würde. Warum Stillarbeit, wenn doch alle in der Gruppe sitzen? Weil sonst bei der folgenden Diskussion leicht die “Lauten”, die “Redseligen”, die “Schnelldenker” sich durchsetzen. Wird ohne einen Moment der stillen Besinnung gleich das kreative Getümmel eröffnet, haben “Leise” und “Langsame” wenig Chance, ihre womöglich besseren Ansätze zu Gehör zu bringen. Ohne Stillarbeit reduziert das Kollektiv also sein Potenzial – und nicht unbedingt auf die Kompetentesten. Hierzu mehr in “Group Genius”.
  • Auf die Stillarbeit folgt die Diskussion der verschiedenen Lösungsansätze. Die Gruppe trägt zusammen, was die Heterogenität ausgebrütet hat. Dabei sollten am besten alle (!) Teilnehmer gehört werden. Auch das wieder eine Maßnahme, um kompetente Zurückhaltende nicht zu verlieren.
  • Die Sammlung der Lösungsansätze erfolgt am besten am Flipchart/Whiteboard. Visual Studio oder eine Diagrammsoftware haben hier keinen Platz. Sie sind schlicht zu beschränkend. Die Kreativitätsphase braucht alle Freiheit und Flexibilität, die sie bekommen kann. Mit einem Stift in der Hand auf einer großzügigen Fläche ist sie am größten.
  • image Lösungsansätze sind keine Programme. In der Kreativphase wird nicht codiert. Es geht um ein Denken auf hohem Abstraktionsniveau. Es geht ums Modellieren. Stefan Lieser hat dafür ein Beispiel in seinem Blogartikel gebracht: eine Sequenz von Kullern (Funktionseinheiten mit klarer Verantwortlichkeit) war sein Modell für die Kata BankOCR. In seiner Lösungsskizze ist keine Klasse zu sehen. Und er hat sich auch nicht durch VS oder TDD oder C# behindern lassen. Wo ein konkreter C# Typname auftaucht, ist der auch nicht ganz scharf als Programmiersprachenkonstrukt gemeint. Er ist für Stefan eher nur ein Platzhalter oder ein Ausrutscher in eine andere Sprache. Ein Idiom, dass knackig eine Intention ausdrückt. Mehr nicht.
  • Damit die Kreativphase auf eine Lösung hin konvergiert, muss am Ende irgendwie gefiltert werden. Entscheidungen sind zu treffen. Wie Stefan bin ich der Meinung, dass dafür ein Konsens (Abstimmung) der denkbare falsche Ansatz ist. Im Konsens steckt nämlich kein Bezug zur Sache. Warum jemand die Hand bei einer Abstimmung hebt oder nicht, ist nicht erkennbar. Vielleicht ist sie von einer Lösung überzeugt, vielleicht genervt (und will deshalb schnell einen Mehrheitsbeschluss, damit es weitergeht), vielleicht unentschieden, aber von einem anderen Teilnehmer persönlich beeindruckt. Eine Abstimmungsmehrheit sagt nur aus, dass für einen Lösungsansatz aus irgendwelchen Gründen mehr Leute die Hand gehoben haben als für einen anderen. Das war´s. Alles andere ist eine hübsche Illusion. Konsens/Demokratie gehört in den Bereich der Politik und nicht in den der Wissenschaft oder des Ingenieurwesens.
    Aber was dann? Statt für Konsens plädiere auch ich für Konsent. Der Begriff kommt aus der Soziokratie und ist hier und hier und hier näher beschrieben. Bei Konsententscheidungen geht es nicht darum, eine Mehrheit für einen Vorschlag zu finden. Wer dafür ist, ist quasi egal. Stattdessen sucht der Konsent nach Widerstand. Er wird daher auch die “Herrschaft des Arguments” genannt. Damit kommt die Sache ins Entscheidungsbild. Widerstände müssen sich nämlich auf den Vorschlag und die Sache bzw. ihren Kontext beziehen. Müdigkeit oder persönliche Beeindruckung haben da keinen Platz. Wer Widerstand leistet, d.h. einen begründeten Einwand hat, der muss auch persönlich hervortreten und sich erklären; damit auch hier keine Stimme untergeht, wird im Konsentprozess ebenfalls jedes Gruppenmitglied befragt. Das fokussiert die Diskussion ungemein. Konsententscheidungen sind daher effizient und effektiv. Das kann man von Abstimmungen nicht so einfach behaupten. Denn Mehrheit bedeutet nicht Effektivität (das Richtige entscheiden) und Mehrheit bedeutet auch nicht Effizienz (schnell entscheiden). Wie wir aus der Politik wissen, kann es bis zu einem Konsens lange dauern. Mehr zum Thema z.B. in meinem Vortrag “Agile Entscheidungen” auf dem Mathema Herbstcampus.

Zweck der Kreativphase ist es, den umzusetzenden Lösungsansatz zu finden. Dabei stolpert die Gruppe selbstverständlich über Lücken oder Divergenzen im Verständnis der Anforderungen. Die Kreativphase überlappt daher mit der vorgelagerten Phase der Anforderungserfassung. Die habe ich oben jedoch nicht aufgeführt, weil sie nicht direkt mit der Softwareentwicklung zu tun hat. Softwareentwickler erheben keine Anforderungen, sondern müssen sie “nur” verstehen. Wer mag, darf aber gern Phase 0: Anforderungserfassungsphase vor die Kreativphase setzen.

imageNicht nur durch die Diskussion und weiterentwicklung verschiedener Lösungsansätze, sondern auch den “Rücksprung” in die Anforderungserfassung ist die Kreativphase also kein linearer Prozess. Sie ist “non routine work” und damit auch außerhalb der Reichweite von üblicher motivations-/produktivitätsfördernden Maßnahmen. Zuckerbrot oder Peitsche wirken nicht, um die Kreativitätsphase zu befördern. Im Gegenteil. Soviel als Anmerkung zur Arbeit in Projekten, die ja noch ausgeprägtere Kreativitätsphasen brauchen. Wer das nicht glaubt, der siehe hier.

Fazit: Lösungsansätze in der Softwareentwicklung entstehen nur in einem kreativen Prozess. Heterogene Kollektive können in so etwas gut sein. Allerdings braucht es dafür Raum und Struktur. Drauflosreden und Abstimmungen sind nicht genug. Gerade divergentes Denken muss also moderiert werden. Das Kollektiv soll sich ja auf den Inhalt konzentrieren, nicht auf die Form. Auch hier gilt wieder das Single Responsibility Principle.

Konvergentes Denken für die Umsetzung

Die Umsetzung eines Lösungsansatzes ist etwas anderes als den Lösungsansatz zu finden. Die Umsetzung braucht kein divergentes Denken, kein Querdenken, keine Vielfalt – sondern System. Bei der Umsetzung ist konvergentes Denken gefragt. Das greift auf einen Fundus an Erfahrungen und Techniken zurück. Es übersetzt den Lösungsansatz als Modell in die konkrete Welt der Implementationstechnologien.

Konvergentes Denken ist nun allerdings in der Gruppe schwierig. Tut mir leid, das berichten zu müssen. Aber so ist es. So sagt es die Psychologie. Wo beim divergenten Denken eine heterogene Gruppe hilft, da hilft beim konvergenten Denken eine homogene Gruppe, also eine Expertenrunde.

Wenn ein Coding Dojo nun aber eine heterogene Gruppe darstellt und vor allem eben keine Experten zum Thema TDD zusammenkommen (sondern Entwickler, die es lernen wollen), dann kann ein Coding Dojo per definitionem für die Umsetzung keine guten Voraussetzungen bieten.

In diesem Licht erscheint es doppelt kontraproduktiv, die Kreativphase wie im letzten Coding Dojo anlässlich des dotnetpro.powerday zu überspringen. Nicht nur wurde kein Lösungsansatz erarbeitet, nein, es wurde die Gruppe sogar sofort in die Phase gestoßen, für die sie am schlechtesten aufgestellt ist. Weder existierte also eine gemeinsame Vorstellung von der Lösung, noch eine gemeinsame Vorstellung von der Umsetzung.

Vielleicht ist Ilker da zurecht stolz auf 2 grüne Tests und ca. 10 Zeilen Domänenlogik für die Kata BankOCR gewesen. Denn bei so schlechten Voraussetzungen ist beides vielleicht eine Leistung.

Frustrierend empfinde ich das Ergebnis dennoch. Denn die Gruppe ist um größere Erfolge betrogen worden, weil man nicht “artgerecht” mit ihr umgegangen ist.

Wie hätte es denn aber besser aussehen können? Meine Vorstellung von einer “artgerechten” kollektiven Umsetzungsphase sieht so:

  • Das Coding Dojo definiert explizit, worauf bei der Umsetzung geachtet werden soll. Das kann einmalig geschehen (“Bei allen unseren Dojo achten wir bei der Umsetzung auf ABC und XYZ.”) oder für jedes Dojo immer weder neu (“Heute wollen wir uns auf XYZ bei der Umsetzung konzentrieren.”).
    Wichtig ist in jedem Fall die ausdrückliche Formulierung eines Umsetzungsrahmens. Denn nur so kann das Dojo bei der Umsetzung effizient gehalten werden. Kommentare, die sich auf Verhaltensweisen beziehen, die nicht im Fokus der Umsetzung liegen, müssen nicht verfolgt werden. Das entspricht wieder dem Konsentprinzip.
  • Während der Umsetzung übernehmen einer oder mehrere Experten in Bezug auf die Umsetzungsgrundsätze die Moderation. Sie setzen selbstverständlich nicht allein um; die Gruppe soll so gut es geht auch die Umsetzung vorantreiben. Aber die Experten leiten die Gruppe an. Sie halten die Gruppe im Rahmen der Umsetzungsgrundsätze, geben Hilfestellungen, regen an, erklären.
    Experte kann jeder sein, der sich in Bezug auf Umsetzungsgrundsätze berufen fühlt. Dazu muss niemand eingeflogen werden. Auch der sprichwörtliche Einäugige kann die Blinden anleiten. D.h. wenn sich auch nur einer aus der Gruppe etwas mehr mit einem Umsetzungsgrundsatz auseinandergesetzt und eine Meinung dazu entwickelt hat, kann er die Moderation über nehmen – und sollte es auch.
  • Nach der Umsetzung folgt selbstverständlich eine Reflexion. Wer mag, kann sie als Phase 3 ansehen. Darauf möchte ich hier aber nicht näher eingehen.

Warum braucht das Kollektiv bei der Umsetzung eine Moderation in Bezug auf die Umsetzungsgrundsätze? Weil die Gruppe zusammengekommen ist, um eben diese Grundsätze zu lernen. Wo aber keine/nur wenig Kompetenz ist, entwickelt die sich nicht spontan aus ungeleiteten, tappenden Versuchen einer heterogenen Gruppe.

Wenn man 10jährige in einem Raum sperrt mit einem Haufen elektrischer Bauteile und dem Auftrag, eine Lampenwechselschaltung zu bauen, ist kaum zu erwarten, dass da etwas herauskommt. Die Gruppe wird sich nicht das Wissen aneignen können. Zusammen mit einem Lehrer jedoch ist das möglich. Der baut die Schaltung nicht selbst, lenkt aber immer wieder die Aufmerksamkeit. Didaktik und Methodik müssen stimmen. Dann findet effizientes und effektives Lernen statt.

Bei einem Coding Dojo ist das nicht anders. Ohne Anleitung findet kein verlässliches Lernen in Bezug auf die ausgelobten Inhalte statt. Das sind meist die Umsetzungsgrundsätze (z.B. TDD, Architektur, OOP). Experten führen die Gruppe hin zur Kompetenz in Bezug auf die Umsetzungsgrundsätze. Sie greifen dabei so wenig wie möglich in den Gruppenprozess ein, aber soviel wie nötig, um den Fokus zu halten.

Irgendwas kann natürlich jeder auch ohne Anleitung lernen. Ich z.B. habe beim letzten Dojo gelernt, wie man rechteckige Blöcke in VS2010 markiert. So nett das aber auch ist, dafür gehe ich nicht ins Coding Dojo. Das kann ich auch bei einer Plauderei einer .NET User Group erfahren.

Fazit: Damit die Umsetzung eines Lösungsansatzes zügig und erfolgreich ist, braucht es Können. Wo das Können fehlt, muss es über Experten in die Gruppe eingebracht werden. Aber auch wo das Können schon in der Gruppe ist, braucht es Moderation für eine kohärente Arbeit der Gruppe.

Kollektive Intelligenz mit System

Ich schätze Ilker für seine hochmotivierte Art, Dojos durchzuführen. Und ich schließe mich seinen Latifa-Werten an.

Aber ich möchte bei ihnen nicht stehenbleiben. Sie sind für mich nur ein Rahmen, in dem für mich das eigentliche Lernen stattfindet. Und dafür ist meine Vision, dass es verlässlich stattfindet in Bezug auf klar kommunizierte Ansätze in der Umsetzungsphase oder auch der Kreativphase.

Darüber hinaus bin ich auch der Überzeugung, dass solches Lernen nur funktioniert, wenn es nicht eine gewisse Führung gibt. Im besten Fall versteht die mehr vom Lerninhalt als der Rest der Gruppe. Sollte das jedoch einmal nicht der Fall sein, ist noch nicht alles verloren. Allerdings muss die Moderation dann besonders sensibel sein.

Bei allem Willen zu Spaß beim Dojo und selbstverständlich grundsätzlicher Gleichberechtigung aller Teilnehmer glaube ich allerdings nicht, dass demokratische Anwandlungen oder “code first” Denke zielführend sind.

Mir scheint, dass die bisherigen Dojos die Kompliziertheit von Problemen unterschätzen und die Leichtigkeit, mit der sich Ansätze wie TDD lernen lassen, überschätzen. Sie glauben, ohne Kreativitsphase (oder gar Anforderungserfassungsphase) auszukommen. Sie glauben, ohne Expertenmoderation in der Umsetzungsphase auskommen zu können. Ihr Credo: “Durch den Code zur Wahrheit und zur Erkenntnis”

Dass es nicht so einfach ist, zeigen dann aus meiner Sicht die magerer Erfolge der Dojos. Wie gesagt: Irgendwas wird schon gelernt. Aber wird das gelernt, was sich die Dojo-Macher wünschen? Ich bezweifle es. (Wenn Sie sich überhaupt etwas wünschen jenseits des Barnum-Mottos “Hier ist für jeden was dabei.”)  Wird gelernt, was sich die Teilnehmer wünschen? Ich bezweifle es. (Wenn die überhaupt einen konkreten Lernwunsch haben und nicht bloß aus Neugierde kommen.)

Damit will ich nicht das Engagement bisheriger Dojo-Macher kritisieren. Im Gegenteil! Ich finde es sehr cool, dass wir hier in der .NET-Welt eine solche Szene entwickelt haben und eifrig diskutieren. Nochmal danke an Vorreiter Ilker!

Aber was am Anfang gut und ausreichend gewesen sein mag, ist es vielleicht jetzt nicht mehr. Der Geschmack kommt beim Essen. Und da es nun Katas und Dojos gibt, ist es – so scheint mir – an der Zeit, weiter zu gehen. Bisher war Dojo 1.0. Ich möchte jetzt Dojo 2.0. Ich möchte Coding Dojos nach oben skizziertem Schema, die noch mehr bieten als die bisherigen. (Oder vielleicht nicht mehr, sondern Anderes.)

image Und deshalb präge ich jetzt mal einen weiteren Dojo-Stil: den Schwarm-Stil. Ilkers Stil ist der Latifa-Stil, meiner der Schwarm-Stil. Warum Schwarm in der Stilbezeichnung? Das ist für mich eine Anspielung auf das Buch “Der Schwarm” von Frank Schätzing. Darin kommt eine Intelligenz vor, die sich aus “sichtbaren” Individuen zusammensetzt, eine kollektive Intelligenz, eine Schwarmintelligenz.

Mir ist klar, dass am Begriff Schwarmintelligenz eine Menge hängt, was nicht zum Coding Dojo passt. Aber egal ;-) Ich finde ihn knackig und es steckt auch das Kollektiv drin.

Jetzt stellt sich nur die Frage, wann und wo das erste Schwarm-Stil Coding Dojo stattfindet. Mal überlegen… Wenn es konkreter wird, berichte ich hier im Blog.

Dienstag, 8. Juni 2010

Zwischenmahlzeit: Kurzvorträge zum Mittag in Karlsruhe, freier Eintritt

Wer mag sich zwischendurch inspirieren lassen? Das ist nämlich am Donnerstag 10. Juni 2010 in Karlsruhe möglich. Leicht verdaubare Happen für den Entwicklergeist statt Suppenkoma bieten nämlich acht Abschlussvorträge eines Rhetoriktrainings.

Von 13:00 Uhr bis ca. 14:30/15:00 Uhr halten die Absolventen des Trainings 10-15 minütige Kurzvorträge in der Albert-Nestler-Str. 10 im Raum Paris des Technologiezentrums bei der andrena objects ag. Hier ein Auszug aus der Themenliste:

  • Umstieg von .NET 3.5 auf .NET 4.0
  • Deliberation und Gruppenentscheidungen
  • Scrum
  • eclipse BIRT
  • Einblick in die Sprache R

Der Eintritt ist natürlich frei. Die Teilnehmer, meine Trainer-Kollegin Renate Klein und ich freuen uns über jeden, der seine (verlängerte) Mittagspause bei ein wenig geistiger Anregung mit uns verbringt. Es gibt Spannendes zu hören. Und die Teilnehmer profitieren vom unvoreingenommenen Feedback eines größeren Publikums.

Also, wie wärs?

image

Freitag, 4. Juni 2010

Intensiv, im Team, kostenlos – Das Clean Code Developer Praktikum

image  Clean Code Developer (CCD) werden, hat weniger mit Technologien zu tun, als vielmehr mit Gewohnheiten und Konzepten. CCD-Tugenden zu vermitteln stellt daher besondere Anforderungen an Trainer. Wie stellen die dann sicher, dass sie sie erfüllen?

Stefan Lieser und ich haben in den letzten 14 Monaten einige CCD-Trainings durchgeführt und fühlen uns durchaus wohl mit den Ergebnissen. Aber wir hätten die CCD-Initiative ja nicht begründet und auch noch die Reflexion auf den Werte-Schild gehoben, wenn wir selbst nicht danach leben wollten und würden.

Deshalb finden wir es an der Zeit, über unsere Trainings zu reflektieren. Das Feedback aus den bisherigen Trainings haben wir analysiert; daraus konnten wir wertvolle Hinweise ableiten. Aber einige Aspekte lassen sich schwer mit Fragebögen erheben. Wir meinen, dass sich Konzepte, Vorgehensweisen und Didaktik nochmal ganz anders analysieren und reflektieren lassen, wenn sie ganz bewusst von Anfang an Thema sind, wenn sozusagen ein Training in einer “Meta-Atmosphäre” stattfindet.

Für ein solches Training, bei dem wir nicht nur etwas weitergeben, sondern selbst viel lernen wollen, können wir ja aber natürlich kein Geld verlangen. Es wäre auch kein normales Training, sondern eher… tja, was denn? Wir haben es mal Praktikum genannt.

Der Deal

Im Juli bieten Stefan Lieser und ich ein Praktikum an, in dem wir 5 Tage mit 5 “Praktikanten” 1 Projekt nach CCD-Manier durcharbeiten wollen.

Dieses CCD-Praktikum ist kostenlos für die Teilnehmer.

Wir bringen unsere CCD-Erfahrung ein. Die Teilnehmer sollen also etwas lernen. Aber wir wollen das – wie gesagt – auf einem anderen Niveau als in einem üblichen CCD-Training tun. Statt in kleinen Schritten Inhalte zu vermitteln, wollen wir in großen Sprüngen voran. Wir wollen mehr anwenden, als erklären. Denn nur dann kommen wir wirklich weiter bei einigen CCD-Bausteinen.

Die Teilnehmer müssen daher schon ein gewisses Erfahrungsniveau in Bezug auf CCD und .NET-Entwicklung haben. Deshalb erlauben wir uns, ein Auswahlverfahren vorzuschalten. Interessierte bewerben sich durch Lösung von zwei Aufgaben.

Keine Angst, das sind keine schlimmen Aufgaben. Wer es ernst meint mit CCD, wird sie leicht lösen können. Hier ein Beispiel für eine Einreichung zu Aufgabe 1 von Steven Weiß.

Also, wie wär´s? Wer hat Lust und macht mit? Es gibt was zu lernen, es gibt was zu schaffen – und es gibt die Möglichkeit, uns mal so richtig die Meinung zu sagen ;-)

Hier mehr Infos zur Termin und Ort sowie Hinweise zur Bewerbung auf der Seite des Professional Developer College.

Wie sind sehr gespannt auf eure Beiträge!

Donnerstag, 3. Juni 2010

Wenn das Ziel der Weg ist – Über typische Verwechslungen [OOP 2010]

Erfolgreiche Typen haben immer klare Ziele. Ohne Ziele geht nix. “10% mehr  Umsatz im nächsten Jahr!” oder “Maximal 1 Bug Report pro Monat im Support” oder “Feature X bis zum 30.6.2010 realisieren” – das sind Ziele für echte Männer (und gern auch Frauen, wenn sie sich angesprochen fühlen). Die sind auch total SMART – ist zumindest in Bezug auf A=Attainable und R=Relevant zu hoffen.

Soweit der Stand der Ziel-Dinge. Den habe ich auch schon mal versucht zu verinnerlichen. Fällt mir aber für mich selbst oft nicht ganz leicht; SMARTe Ziele allerdings für andere zu fordern, ist etwas ganz anderes ;-) Doch darum geht es mir nicht. Ich bin vielmehr über etwas Grundsätzliches gestolpert.

Solche oder ähnliche Ziele sind wohl nötig “im Business” und auch sonstwo. Ok. Dazu kommen dann aber noch aus den Zielen abgeleitete Rahmenbedingungen. “Um das Ziel ‘10% mehr Umsatz im nächsten Jahr’ zu erreichen, bekommen Sie das Budget X.”, “Um maximal 1 Bug pro Monat zu erreichen, erhalten Sie die Ressourcen Y” usw. Ziele sind quasi nicht von Grenzen zu trennen, in denen sie erreicht werden müssen. Sie sind immer an irgendwelche Budgets gekoppelt (Geld, Zeit, Menschen, Maschinen, Material usw.).

Das hört sich auch plausibel an. Die Rahmenbedingungen stehen für den maximalen Preis, den man zahlen will, um ein Ziel zu erreichen. Und da immer viele Ziele zu erreichen sind, die zur Verfügung stehenden Ressourcen jedoch meist begrenzt sind, müssen sie in zielindividuelle Budgets partitioniert werden. Oder?

So plausibel sich diese Argumentation anhört, mir scheint sie ganz grundsätzlich an einem Missverständnis zu leiden. Oder sogar an mehreren.

Missverständnis #1: Das Ziel ist der Weg

Da ist zum einen das Missverständnis, Ziele seien irgendwie unbeweglich. Klar, das gibt es. In sehr künstlichen Umgebungen wie Sportschießständen sind Ziele meist unbeweglich. Ich habe selbst mehr als 10 Jahre Leistungssport auf solchen Schießständen getrieben und weiß, wovon ich rede. Selbst solche starren Ziele sind schwer zu treffen. Im Sportschießen bringt man deshalb einiges Material in Anschlag (sogar im doppelten Sinn). Da gibt es Schuhe, Jacken, Hosen, Handschuhe, Mützen, Riehmen um die Bewegungsfreiheit des Schützens einzuschränken – auf das er das Ziel leichter erreiche, äh, treffe. Trotzdem meinen Glückwunsch dem, der in diesem Rahmen Höchstleistungen vollbringt.

Allerdings, da wollen wir ehrlich sein, realitätsnah ist das Sportschießen nicht. Es ist eine tolle Disziplin, in der man eine Menge lernen kann – nur nicht den Umgang mit der Waffe in realen Situationen. Die sind nämlich insofern entscheidend anders, als dass man sich erstens selten auf sie so vorbereiten kann und zweitens – das ist der Knackpunkt – allermeistens mit Zielen aufwarten, die nicht stillhalten.

In der realen Welt sind Ziele immer das, was sich bewegt. Militär, Polizei und “außersportliche” Waffenfreunde wissen das. Deren Schießstände sehen deshalb auch anders aus. Dort bewegen sich die Ziele.

Die Kunst, Ziele im realen Leben zu treffen, besteht also darin, nicht zu erstarren, sich nicht einzuschnüren, sondern so beweglich wie das Ziel zu bleiben – und es trotzdem zu treffen. Managerseminare sollten deshalb vielleicht mal Völkerball ins Programm nehmen – da bewegen sich nämlich anders als bei Handball oder Fußball die Ziele. Oder wie wäre es mit einer Runde Paintball? Die würde nicht nur Erkenntnise zur Natur realer Ziele, sondern auch zur persönlichen Kondition bringen ;-) Doch das nur am Rande…

Also: Ziele “in der Natur” sind beweglich. Deshalb müssen Jäger ebenfalls beweglich sein. Menschen sind den Tieren insofern überlegen, als dass sie nicht nur körperlich, sondern auch geistig beweglich sind.

Umso verwunderlicher ist es, dass diese Beweglichkeit üblicherweise massiv eingeschränkt wird, wenn es um Ziele in Unternehmen geht. Nicht nur sind die merkwürdig unnatürlich fix; nein, auch die Beweglichkeit der Mitarbeiter, die sie treffen, äh, erreichen sollen, ist eingeschränkt.

Das fühlt sich für mich so an, als sei eigentlich der Weg, d.h. die Bewegung in den Randbedingungen oder gar die Randbedingung selbst das eigentliche Ziel. “Wichtig ist, dass Ihr das Budget einhaltet!” Besonders deutlich wird das Missverständnis, wenn Budgets ausgeschöpft werden müssen. Müssen! Denn sonst droht ja, dass das Budget im nächsten Jahr kleiner wird. Unverbrauchtes Budget ins nächste Jahr (oder zum nächsten Projekt) zu retten, ist kaum möglich.

Philosophisch-spirituell ist es hübsch, vom Weg als Ziel zu sprechen. In wirtschaftlichen Zusammenhängen fühlt sich das jedoch komisch an. Weg und Wegbegrenzungen dürfen nicht das Ziel sein. Wo das passiert, wird der Unternehmenszweck pervertiert und die Motivation der Mitarbeiter mit Füßen getreten. (Ok, ausgenommen die der Mitarbeiter, die dafür verantwortlich sind darauf zu achten, dass der Weg als Ziel eingehalten wird.)

Also: Ich plädiere für einen natürlichen Umgang mit Zielen. Wenn schon Ziele, dann solche, die sich bewegen dürfen. Wenn sich im Verlauf eines Jahres herausstellt, dass 10% Umsatzzuwachs nicht zu erreichen sind (aufgrund zu geringen Budgets oder sonstiger Faktoren), dann muss man den eigenen Anschlag nachführen. Die Objekte der Begierde sind da, wo sie sind – und nicht dort, wo man mit seinen Rahmenbedingungen hinzielt. Man muss sich suchen – dafür gibt es einen Sucher bzw. Kimme und Korn – und man muss sich ihnen nachführen, wenn sie sich bewegen. Das nennt man Zielen. Zielen ist eine Tätigkeit, kein Zustand.

Wer ein Ziel benennt, der muss das im Blick haben. Er muss seinen Jägern vertrauen, dass sie gut zielen können. Und er muss damit leben, dass sich die Ziele bewegen und die Jäger Freiheit brauchen, um ihnen folgen zu können. Und schließlich: Es kann die Zielverfehlung keine Sache der Ehre und der quasi persönlichen Enttäuschung sein. Zielverfehlung ist vielmehr der Normalfall in einer Welt hoch beweglicher oder im Nebel verborgener Ziele.

Zielverfehlung also mit noch engeren Rahmenbedingungen zu beantworten ist grob kontraproduktiv. Nicht Einschnürung hilft Jägern, sondern Befreiung, Mobilität, Autonomität.

Das haben Polizei und Militär schon lange begriffen. Die Helden sind heute nicht mehr Heere, sondern hochmobile, intelligente, autonome Einsatzkommandos – die vor Ort jeder unvorhergesehenen Bewegung ihrer Ziele folgen können.

Missverständnis #2: Das Ziel ist der Zweck

Dann gibt es noch ein zweites Missverständnis. Es werden nämlich oft Ziele für Zwecke gehalten. “Warum machen wir das alles hier, Leute? Um Geld zu verdienen! Und deshalb brauchen wir im nächsten Jahr 10% mehr Umsatz.” So wird ein Ziel schnell als Zweck geadelt.

Doch das halte ich für ein großes Missverständnis. Weder ist “10% mehr Umsatz” ein Zweck, noch ist “Geld verdienen” ein Zweck. Beides sind nur Mittel. Sie sind Mittel zu einem Zweck, zu etwas “Höherem”.

Da will ich jetzt nicht gleich Weltfrieden und Klimaziele beschwören – aber ein bisschen geht´s schon in die Richtung. Zweck ist, wofür etwas getan wird. Was ist der Antrieb hinter einer Unternehmung? Um dessentwillen werden Menschen zu Kunden. Der Zweck ist die Antwort auf die Frage: “Warum sollte sich irgendjemand für uns interessieren?” (Die Betonung liegt dabei auf “uns”, denn die “Identität der Firma” ist am Ende das einzige, was sich nicht austauschen lässt. Sie ist das, was sich nicht in ein fernes Land auslagern lässt, um es billiger herzustellen.) Er drückt aus, warum einer/eine Firma wirklich etwas tut.

Wenn der Zweck also “Geld verdienen” sein soll, dann ist die Frage, ob irgendjemand deshalb Kunde würde. Nein, ich glaube nicht. “Ach, du willst Geld verdienen? Klar, dann kaufe ich dein Produkt.” So funktioniert es nicht.

Aber: “Wir bauen die besten Autos der Welt”, ja, das ist ein Zweck. Oder “Unser Unternehmen gibt es, weil wir verstanden haben, was Ihnen bei der Ernährung am Arbeitsplatz fehlt.” Oder “Wir glauben daran, dass Software ohne Support auskommen kann.”

Das sind Zwecke, denn dazu können Sie sagen “Dafür kämpfe ich!”, “Dahinter stehe ich!”, “Das ist auch mein Anliegen!”, “Es gibt mir etwas, wenn ich mithelfen kann, diesen Zweck zu erreichen.”

“Viel Geld verdienen” oder “10% mehr Umsatz” oder “1 Bug pro Monat” sind keine Zwecke. Es sind nur Ziele. Deshalb sollte jede offene oder unterschwellige Überhöhung sofort angezeigt werden. Ziele dürfen nicht zu Zwecken umgemünzt werden, um ihnen mehr Gewicht zu verleihen.

Das bedeutet im Umkehrschluss: Wenn Ziele eben nur Ziele sind, dann können sie jederzeit hinterfragt werden im Sinne von Zwecken. Wer ein Ziel benennt, der muss Antwort darauf geben können, inwiefern es welchem Zweck diene. Welchem Unternehmenszweck dient “10% mehr Umsatz im nächsten Jahr”? Welchem Zweck dient “Nur 1 Bug pro Monat”?

Tja, bei solchem Nachfragen kann dann herauskommen, dass “10% mehr Umsatz” keinem Unternehmenszweck dient. Denn “Das beste Callcenter für Medizinprodukte!” als Zweck zu haben, bedeutet nicht unbedingt, “10% mehr Umsatz im nächsten Jahr” machen zu müssen. Es könnte sein, dass ein Ziel wie “Die Fluktuation der Mitarbeiter um 10% verringern” (bei gleichem Umsatz) dem Zweck viel dienlicher ist.

Fazit

Es ist so eine Sache mit den Zielen. Alle sollen welche haben – dafür gibt es ja auch Personalgespräche mit Zielfestlegungen. Aber der richtige Umgang mit ihnen, die passende Kultur zur Natur von Zielen, die sich in der realen Welt bewegen, ist nicht leicht zu finden. Und die Gefahr der Verwechslung von Ziel mit Zweck lauert überall und umso mehr, je verzweifelter man versucht, das Ziel zu rechtfertigen und zu erreichen.

imageWas tun? Mehr Völkerball spielen könnte helfen ;-) Oder mehr mit den Menschen umgehen, statt mit Human Resources. Denn wer letztlich Menschen, Maschinen, Geld und Zeit über einen Leisten schlägt, weil er in allem nur Ressourcen sieht, der vergisst, was am Ende des Tages der ultimative Zweck aller Unternehmen ist: den Menschen zu dienen. Egal, ob sie im Unternehmen sind oder draußen. Womit wir dann doch bei der Philosophie angelangt sind. Denn dass Menschen immer nur Zweck und nicht Mittel sein sollen, das sagte weiland Immanuel Kant.