You never code alone!

Meine letzte Woche in der Arbeit würde ich gerne the cleverbridge-University-Woche nennen, so großartig war sie. Wir haben 3 von 5 Tagen damit verbracht, unseren Code, unsere Prozesse, unseres Miteinander zu analysieren, zu sezieren, zu verbessern:

  • Dienstag hatten wir fast einen ganz Tag Architektur-Workshop um die Vision und die Strukturen für unseren Code zu definieren.
  • Den Freitag haben wir gemeinsam bei der dotnet-cologne 2014 verbracht.

Das wichtigste hat allerdings am Donnerstag stattgefunden: wir haben uns einen ganz Tag Zeit genommen, um von Ilker, meinem TDD-Mentor, so viel wie möglich über Specs, Tests, Teams und Kommunikation zu verstehen.

Es geht nichts über Verstehen!

from requirement to specifications
Wie schafft es ein Team, das und nur das zu bauen, was der Kunde braucht?

  1. Findet alle zusammen – product owner, Entwickler, Tester – das richtige Wording, die “ubiquitous language” heraus, die die Anforderung beschreiben
  2. Versteht alle zusammen, worum es geht.
  3. Definiert zusammen das Feature
  4. Schreibt zusammen die Akzeptanzkriterien

Wie werden eigentlich eine paar Menschen zu einem Team?

Dies ist wahrscheinlich das Problem aller Firmen weltweit, die sich weiterentwickeln möchten. Und das zu Recht: stell dir vor, du bist ein C#-Entwickler mit zum Beispiel Schwerpunkt Web, hast JavaScript warscheinlich noch nie als Programmiersprache betrachtet und von der Arbeit der anderen C#-Entwickler weißt nichts, außer dass sie existiert und sie irgendwann später erfolgen wird, nachdem du deine Aufgaben schon längst erledigt hast. Einen Abteilungsleiter hast natürlich auch und deine Entscheidungsgewalt beschränkt sich auf “soll ich foreach oder lieber LINQ verwenden?”

Das ist allerdings nicht alles: deine Aufgaben überschreiten niemals die Grenzen deiner Abteilung, genauso wenig wie dein Verständnis über die Anforderungen. Und das stört dich seit langem und nicht nur dich sondern auch den JavaScript-Typen und die Frontend-Entwicklerin und wenn du Glück hast, dann auch deinen Abteilungsleiter. Wenn das der Fall ist, dann hat deine Firma Glück: ihr seid offen für ein Crossfunktionales Team. Ihr musst nur diese Frage bejahen:

Bin ich bereit, jede Rolle in diesem Team zu erfüllen?
Auch mit der Gefahr, dass ich das nicht kann? Wenigstens noch nicht, oder noch nicht gut genug…

Jedes Team braucht noch ein paar Zutaten:

  1. Ein Ziel
  2. Eine Partizipation – eine gemeinsame “Teilhaberschaft”
  3. Den Respekt der Individualität
  4. Die gemeinsame Verantwortung

oder wie Ilker sagt “oder mindestens 3 davon plus jemanden, der die anderen die ganze Zeit daran erinnert”.

 

Ich will nicht behaupten, dass wir bereits alles darauf haben – aber wir sind auf dem besten Wege dahin. Und was das Wichtigste ist: wir werden diesen Weg sicherlich nicht verlassen.

Open Space – agiler geht es nicht

Letztes Wochenende war wieder Hightide für Entwickler: es war “Open Space Süd Time” in Karlsruhe. Es gab viele bekannte und viele unbekannte (= neue) Gesichter. Es gab sogar ich glaube fünf weibliche Teilnehmer und auch noch einen Hund 😀

Wegen den vielen neuen Teilnehmer war es nach mehreren Jahren wieder notwendig, die Prinzipien zu erklären, die bei einem Open Space gelten:

Regeln

Im Open Space gibt es vier Prinzipien (eigentlich eher Beobachtungen, wie sich die Welt zeigt)

  1. Wer auch immer kommt, es sind die richtigen Leute – einer oder 25 ist egal, und jeder ist wichtig und motiviert.
  2. Was auch immer geschieht, es ist das Einzige, was geschehen konnte – Ungeplantes und Unerwartetes ist oft kreativ und nützlich.
  3. Es beginnt, wenn die Zeit reif ist – wichtig ist die Energie (nicht die Pünktlichkeit)
  4. Vorbei ist vorbei – Nicht vorbei ist Nicht-vorbei – wenn die Energie zu Ende ist, ist die Zeit um.

und ein Gesetz:
Gesetz der zwei Füße

Das Gesetz der zwei Füße ist Ausdruck der Freiheit und Selbstverantwortung: Der Teilnehmer bleibt nur so lange in einer Gruppe, wie er es für sinnvoll erachtet, also solange er etwas lernen und/oder beitragen kann.
(Wikipedia)

Es gibt auch eine Beschreibung der Teilnehmer:

Teilnehmer

Bei Open Space gibt es nicht den richtigen oder falschen Teilnehmer. Jeder ist willkommen, der oder die sich direkt betroffen und motiviert fühlt, etwas verändern zu wollen. Es sollen möglichst unterschiedliche Menschen eingeladen werden (Berufsgruppen, Verantwortungsbereiche, Alter, aber auch Kunden, Nachbarn, etc.), darunter die wesentlichen Meinungsmacher und Multiplikatoren.

Nach diesem letzten Open Space würde ich diese Definition erweitern:
jeder, der teil nimmt muss zu einem offenem Gespräch bereit sein. Das bedeutet, er muss nicht nur neugierig auf die Meinung der anderen sein, sondern muss bereit sein, seine Ansichten zu revidieren, wenn er sich geirrt hat.

Kommt jemand hin, um etwas zu präsentieren anstatt zu diskutieren: dafür ist Open Space nicht geeignet. Das ist keine Konferenz, wo die Leute bezahlen und hoffen, dass es sich lohnt 😉
Andererseits kommt jemand ohne irgendwelche Ansichten dahin, hat er die Möglichkeit, sie hier zu formen, die Meinung der anderen an zu hören und seine eigenen Schlussfolgerungen zu ziehen.

Was hat das alles mit Agilität zu tun? Schauen wir mal, was während diesen 2 1/2 Tagen immer wieder – in Zyklen sozusagen – passiert:

  1. – wir beschreiben Probleme oder Angebote und schmeißen sie in die Runde. Es werden die Interessenten gezählt und auf die Karte notiert => hört sich wie Planungsmeeting an, oder?
  2. – wenn das Bord voll ist – wie ein Backlog – , muss die zeitliche und räumliche Reihenfolge definiert werden, und zwar nach Sinn und Machbarkeit => genau wie in einem Priomeeting?
  3. – jetzt kommt die größte Herausforderung: welchen Session soll ich besuchen? Welcher hat für MICH die höchste Prio? Wie organisiere ich meine Zeit so, dass mein “Backlog” auch abgearbeitet wird?

Die ganzen Zeit stellen wir Fragen gestellt und Antworten überlegt: Anforderungen an andere definiert und selbst welche erfüllt. Wenn diese Anforderungen sich geändert haben – siehe spontane Coding Dojo von 18 bis fast 20 Uhr am Samstag Abend – dann wird vom Team sofort eine Entscheidung getroffen: passt es noch in diesem oder erst im nächsten Sprint (also am zweiten Tag).

Wir versuchen ununterbrochen durch die richtige Kommunikation die Lücken zu schließen, die wegen den Unterschiede in Erfahrung, Ausbildung, Alter, Geschlecht, Herkunft usw. existieren. Wir haben eine zeitliche Vorgabe – jeder Timeslot ist 45 Minuten lang – den wir zwar wahrnehmen aber uns damit nicht unter Druck setzen lassen.

Und jeden Abend wird der wichtigste Teil eines agilen Prozesses zelebriert: die Retrospektive – bei einem kühlen Bier 🙂

Coding Dojo – der Trainingsraum für Entwickler

Definition: A Coding Dojo is a meeting where a bunch of coders get together to work on a programming challenge (the Code Kata). They are there to have fun and to engage in deliberate practice in order to improve their skills.

(Quelle: http://codingdojo.org/)

The Principles of a Coding Dojo
(extracted from the Laurent Bossavit’s Blog: bossavit.com/dojo/archives/2005_02.html)

  1. The First Rule
    One important rule about the Dojo is : At the Dojo one can’t discuss a form without code, and one can’t show code without tests. It is a design training place, where it is acknowledged that “the code is the design” and that code without tests simply doesn’t exist.
  2. Finding a Master
    The master can’t be a master of every forms. I feel quite at ease with recursive functions and list processing e.g. but I think I don’t know how to create even a simple web app. Fortunately, while it’s the first time they really deal with “tail-recursion” some practionners here have done professional web apps for years!
  3. Come Without Your Relics
    Of course, you know how to do it. You know how and why this code is better than that one. You’ve done it already. The point is to do it right now, explain it to us, and share what you learned.
  4. Learning Again
    In order to learn again something, we just have to forget it. But it’s not easy to forget something when you’re alone. It’s easier when we give our full attention to someone who just tries to learn it for the first time. We can learn from others mistakes as well as from ours if we listen carefully.
  5. Slow Down
    Learning something should force you to slow down. You can go faster because you learned some tricks, but you cannot go faster and learn at the same time. It’s OK, we’re not in a hurry. We could do that for years. Some of us certainly will. What kind of deadline will we miss if we spend four more weeks on this subject rather than on four different subjects? More precisely, when we reach the next plateau, is it because we went through the previous one, or is it just because we were flying over it?
  6. Throwing Yourself In
    At some time someone begins to master a subject and wants to approach another one. Those threatened by boredom should throw themselves first into a presentation. The goal is to get back to a good motivation level, ie. an acceptable level of difficulty.
  7. Subjecting To A Master
    If it seems difficult to you, look for other practitionners who can judge your code and could easily show something new about it to you. Ask again until the matter contains absolutely no more difficulty to you.
  8. Mastering A Subject
    If it seems easy to you, to explain it to other who find it difficult. Explain it again as long as they find it difficult.

(Quelle: http://codingdojo.org/)

Seit mehreren Monaten experimentieren wir mit Coding Dojos in der Firma. Nach jedem bisherigen Dojo haben wir etwas gelernt und diese Erkentnisse bei dem nächsten Session gleich angewendet: Wir haben sozusagen die Dojo-Finding-Kata gelöst und eine gute Lösung dafür gefunden, wie wir dabei das meiste lernen können.

Es gibt 2 Levels: für Anfänger und für weniger Anfänger, mit einem gemeinsamem Punkt: alle sind Softwareentwickler. Anfänger bedeutet: neu in der Welt der Tests und/oder neu in C#. Dadurch, dass wir sowohl C# als auch JavaScript-Dojos machen, werden wir uns mal den einen mal den anderen Schuch anziehen müssen ;). Durch diese Aufteilung sind wir in der Lage, eine passende Übung durchzuführen. Die Einladung geht an alle und es bleibt jedem selbst überlassen, zu entscheiden, bei welchem Level er/sie mitmachen möchte. Diese Selbst-Verpflichtung führt automatisch dazu, dass man es ernst.

Was die Form betrifft, haben wir mehrere Varianten ausprobiert:

  • Mit oder ohne Moderator: Erkenntnis: es muss einen Moderator geben, wenn man nicht will, dass der Abend in Frust und Streit endet 😉
  • mit Coder und Driver (Randori Modus): Erkenntnis: der Coder war gleichzeitig der Driver, der andere saß nur da und wartete auf seine ReiheThumbs-down-icon
  • mit Wechsel der Paare nach einer bestimmten Zeit: Erkenntnis: das mentale Ticken einer Uhr hat teilweise zu einer kompletten Blockade geführt. Warum soll man überhaupt einen Stopper verwenden? Niemand sagt einem bei der Arbeit: du hast 5 Minuten für diese Aufgabe sonst müssen wir die Firma schließen!!Thumbs-down-icon
  • ein Dojo für alle, unabhängig von Kenntnissstand: Erkenntnis: ein guter Entwickler, der in C# noch noch nicht so bewandert ist, hat genauso gute oder gar bessere Ideen, als die anderen bzw. braucht länger um den Syntax des Lösungsweges zu verstehen. Das kann dazu führen, dass man sich unterschätztThumbs-down-icon

Nach verschiedenen Diskussionen mit anderen Entwickler, die Dojos in Unternehmen erfolgreich etabliert haben (danke nochmal Ralf und Uli) und nach diesen eigenen Erfahrungen, haben wir uns für die folgende Variante entschieden:

  • die Tastatur geht herum, und nicht der Entwickler (das hat auch immer wieder zu Störungen geführt).
  • Jeder, der dran ist, muss entweder den allerersten Test schreiben oder den vorherigen lösen: das bedeutet, er muss den Code schreiben, wodurch der Test grün wird – nicht mehr und nicht weniger. Danach muss er noch den nächsten Test schreiben, und zwar so, dass er rot ist. (Es gab Fälle, wo die nächste Anforderung – also der nächste Test – gleich mit implementiert wurde.)
  • Es gibt keine zeitliche Begrenzung und niemand muss alleine grübeln. Wenn Fragen oder Mißverständnisse im Raum stehen, sie werden sofort geklärt. Die Fragen müssen trotzdem vom Entwickler formuliert werden: der Lernprozess ist immer da.
  • Der Weg ist das Ziel: wird eine Aufgabe nicht in der Zeit erfüllt, die uns zur Verfügung steht, dann ist das auch ein Erkenntniss, aus dem man lernen kann.

Thumbs-up-icon

Wir verfolgen durch diese Trainingsstunden verschiedene Ziele:
– lernen, wie man Tests schreibt, um eine nachhaltige Qualität abzusichern,
– lernen, wie man Features gegen Code-Veränderungen schützt.
– lernen, wie man eine Anforderung interpretiert,
– lernen, wie man eine Anforderung definiert,
– lernen, wie man eine konstruktive Diskussion führt um sich auf eine Lösung zu einigen,
– lernen, wie man SOLIDen Code schreibt, Abhängigkeiten erkennt und trennt, wie man für Menschen lesbaren Code schreibt.

Die Liste der Lerneffekten solcher Übungen ist sicher viel länger, aber vorerst reicht es, wenn wir das hier schaffen :). Diese Prozesse werden sich sicherlich ändern – genauso wie wir Entwickler. Die Grundlagen aber bleiben bestehen: alles, was wir hier lernen, soll sich – wird sich –  in der täglichen Arbeit wiederspiegeln und uns zu besseren Softwareentwickler und gleichzeitig zu besseren Teamplayer machen.

File provided for Reference Use Only By Microsoft Corporation (c) 2007

Seit ein paar Wochen, wenn ich mit Resharper zu der Implementierung von manchen Microsoft-Funktionen navigieren will, bekomme ich die ganze dll heruntergeladen und danach den ganzen Code zu sehen:

// ==++==
//   Copyright (c)  Microsoft Corporation.  All rights reserved.
// ==--==
namespace System.Globalization {
    using System.Security.Permissions; 
    using System.Runtime.Serialization; 
    using System.Text;
    using System; 
    //
    // Property             Default Description
    // PositiveSign           '+'   Character used to indicate positive values.
    // NegativeSign           '-'   Character used to indicate negative values. 
    // NumberDecimalSeparator '.'   The character used as the decimal separator.
    // NumberGroupSeparator   ','   The character used to separate groups of 
    //                              digits to the left of the decimal point. 
    // NumberDecimalDigits    2     The default number of decimal places.
    // NumberGroupSizes       3     The number of digits in each group to the 
    //                              left of the decimal point.
    // NaNSymbol             "NaN"  The string used to represent NaN values.
    // PositiveInfinitySymbol"Infinity" The string used to represent positive
    //                              infinities. 
    // NegativeInfinitySymbol"-Infinity" The string used to represent negative
    //                              infinities. 
    // Property                  Default  Description
    // CurrencyDecimalSeparator  '.'      The character used as the decimal
    //                                    separator.
    // CurrencyGroupSeparator    ','      The character used to separate groups 
    //                                    of digits to the left of the decimal
    //                                    point. 
    // CurrencyDecimalDigits     2        The default number of decimal places. 
    // CurrencyGroupSizes        3        The number of digits in each group to
    //                                    the left of the decimal point. 
    // CurrencyPositivePattern   0        The format of positive values.
    // CurrencyNegativePattern   0        The format of negative values.
    // CurrencySymbol            "$"      String used as local monetary symbol.
    // 

    [Serializable] 
    [System.Runtime.InteropServices.ComVisible(true)] 
    sealed public class NumberFormatInfo : ICloneable, IFormatProvider
    { 

        // invariantInfo is constant irrespective of your current culture.

        private static NumberFormatInfo invariantInfo;
...

Das ist wunderbar, es ist großartig zu sehen, wie die Klassen Random or DateTime aufgebaut sind. Obwohl ich keine Ahnung habe, warum das passiert… Ich hoffe allerdings, dass es kein Bug ist, und ich weiterhin den Code statt irgendeine Dokumentation sehen werde, auch wenn komischerweise am Ende der meisten Klassen der Titel dieses Artikels steht: File provided for Reference Use Only By Microsoft Corporation (c) 2007 😉

Das alles ist cool, aber noch nicht wirklich ein Grund für einen Blogeintrag. Den folgenden Kommentar wollte ich euch aber nicht vorenthalten:

        // READTHIS READTHIS READTHIS 

        // This class has an exact mapping onto a native structure defined in COMNumber.cpp

        // DO NOT UPDATE THIS WITHOUT UPDATING THAT STRUCTURE. IF YOU ADD BOOL, ADD THEM AT THE END. 

        // ALSO MAKE SURE TO UPDATE mscorlib.h in the VM directory to check field offsets. 

        // READTHIS READTHIS READTHIS

        internal int[]  numberGroupSizes = new int[] {3};
...
        internal bool m_useUserOverride=false;    // NEVER USED, DO NOT USE THIS! (Serialized in Everett)
...

😆

communicare ergo sum

Wie ich schon in dem Artikel über NOS Süd erwähnte, eines der interessantesten Themen, worüber wir in Karlsruhe debattiert haben, ist das Berufsbild des Softwareentwicklers. In einem Punkt waren wir uns alle einig:  der Softwareentwickler muss ein kleines Kommunikations-Genie sein!
Er muss sich in der Lage seines Gesprächspartners versetzen können, um Antworten auf noch nicht gestellten Fragen auszusprechen zu können; er muss seinem Gegenüber diplomatisch den rechten Weg zeigen, vor allem da dieser meistens überhaupt keinen blassen Schimmer von dem hat, was alles in einem Softwareprojekt möglich ist bzw. beachtet werden muss.

In den letzten Tagen habe ich den Eindruck bekommen, dass die Sommerhitze viele dazu gebracht hat, ihr sonst immer vorhandenes Talent im Bereich der Kommunikation zu vergessen. Alle diese Leute sind hochqualifizierte IT-Professionals, die, wenn sie sich zusammentun würden, alles schaffen könnten, was sie sich nur in den Kopf setzen. Ich habe bisher von ihnen wahnsinnig viel gelernt und das wird sich sicher niemals ändern.
Ich hätte allerdings diese Diskussion etwas anders geführt, und zwar nach diesen Regeln:

  1. Niemals in der Hitze des Gefechts antworten: das ist wahrscheinlich das Schwierigste, und in den heutigen digitalen Welt, wo man schnell und von überall antworten kann, ist es fast unmöglich diesem Drang zu wiederstehen.  In der  Twitter- und Blog-Welt verläuft die Kommunikation nicht mehr nur zwischen den einzelnen Beteiligten, sondern vor der “versammelten Mannschaft”. Dies führt unweigerlich dazu, dass jedes Wort schwerwiegender ist und die Folgen eines falsch gewählten Ausdruckes viel gravierender sind.
  2. Niemals jemanden öffentlich Beleidigen: auch wenn jemand einen Fehler gemacht hat, hat es gar keinen Sinn, ihn in eine Situation zu bringen, bei der er mit dem Rücken zur Wand steht. In 90% der Fällen würde aufgrund des Prinzips “Angriff ist die beste Verteidigung” einfach nur zurück-beleidigt werden, wahrscheinlich auf einer noch schlimmeren Art, um seine “Stärke” zu beweisen. Die Leute, die trotzdem objektiv bleiben und ihre eventuelle Schuld eingestehen sind sehr, sehr selten. Und noch seltener die, die sich nach eine Beleidigung öffentlich entschuldigen.
  3. Dem Anderen immer eine Wahl lassen: das Ziel sollte doch immer ein Konsens sein, sonst würde man einfach nur Befehle erteilen und dies ist bekanntlich keine Kommunikation. Also bevor man ein Gespräch beginnt, muss man sich im klaren sein, was er von dem Anderen erwartet und ob das überhaupt fair bzw. machbar ist.
  4. Niemals einen verlorenen Kampf beginnen: wenn es mir klar ist, dass der Gesprächspartner niemals meinem Wunsch entsprechen würde, wozu dann eine Diskussion anfangen? Man muss nicht immer alles durchsetzen, es geht ja hier nicht um Leben und Tod.
  5. Ich entschuldige mich bei den Lesern, die sich jetzt berechtigt fragen, um welche Diskussion es hier geht. Dies ist unwichtig, “vergangen sei vergangen und Zukunft ewig fern … “, es ist viel wichtiger, dass man endlich den gewünschten Konsens findet.
    Diese Community ist noch sehr jung und sehr empfindlich, es würde uns allen schaden, sie teilen zu müssen.
    Ich bin derselbe Meinung wie Mike, unser Ziel ist lernen und lehren mit Freude und Leidenschaft.