Agile Praktiken bei Softwaretransitionen
Jonathan Frankenberger
Jonathan Frankenberger

// //
Lesedauer: 9 Minuten

Agile Praktiken

bei Softwaretransitionen


Eigentlich wünschen wir es uns in der Softwareentwicklung doch so: Ein möglichst stabiles Team arbeitet von der ersten Idee bis zur Ablösung konstant an einem Produkt. Klar, verlassen einzelne Mitglieder das Team und neue kommen hinzu, im Kern handelt es sich jedoch um ein mehr oder weniger stabiles Team.

In der Realität kommt es aber durch einen Wechsel von Zuständigkeiten oder Lieferanten immer wieder zu Situationen, in denen ein Software-System an ein anderes und völlig neues Team übergeben wird. Dieser Vorgang wird als Transition bezeichnet. Die spannende Frage ist nun, wie wir diese Transition möglichst gut ausgestalten können. Glücklicherweise hilft uns hierbei der Griff in den agilen Werkzeugkasten. Da agile Softwareentwicklung als eines ihrer Hauptprinzipien auf gut funktionierende Teams setzt, liegt es ihr quasi schon im Blut, für einen teamweiten effektiven Aufbau von Wissen und Fähigkeiten zu sorgen.  

Im weiteren Verlauf zeige ich, wie die folgenden fünf Praktiken gerade im Kontext von Transitionen wirkungsvoll sein können:

Fünf Zettel mit den Worten „Entwickler“, „Entwickler“, „Entwickler“, „Entwickler“.

    Für die wirkungsvolle Anwendung dieser Praktiken empfehle ich für den Zeitraum der Transition aus alten und neuen Teammitgliedern ein gemeinsames Team zu bilden. Mit der Zeit können dann nach und nach die alten Teammitglieder das gemeinsame Team verlassen, um eine weiche Transition zu ermöglichen.

    Pair-Programming

    Unter Pair-Programming verstehen wir ein Vorgehen, bei dem zwei Entwickler (vor Ort oder remote) an einem Arbeitsplatz arbeiten, um gemeinsam ein Stück Code zu entwickeln. Dabei folgen sie einem vorher festgelegten Interaktionsmuster. Das Bekannteste ist das Driver-Navigator-Muster, bei dem eine Person programmiert (Driver), während die andere reviewt und sich über das grundlegende Design Gedanken macht. Die Personen tauschen ihre Rollen dabei in verhältnismäßig kurzen Zeitabständen, meistens mehrfach pro Stunde.

    Auf den ersten Blick mag das im Kontext von Transitionen wie kalter Kaffee klingen. Dort kennt man seit vielen Jahren das Prinzip des Shadowing und Reverse-Shadowing. Im Vergleich zum Pair-Programming hat dieses Vorgehen jedoch einige Nachteile:

    • Wie der Name „Shadowing“ nahelegt, ist die Person, die gerade im Shadowing ist, auf eine eher passive Rolle festgelegt. In der Praxis führt dies zu stundenlangem Zuschauen mit vielleicht gelegentlichen Rückfragen. Nicht gerade sehr motivierend.
    • Der Zuschauende kommt über lange Zeit nicht ins Handeln. Echtes Können wird aber erst im konkreten Handeln aufgebaut. Beim Pair-Programming wird dies durch den frühen und wiederholten Wechsel in die Driver-Rolle sichergestellt. Und auch der Navigator schaut nicht passiv zu, sondern greift durch sein Feedback aktiv in die Entwicklung ein.
    • Im großen Unterschied zum Shadowing ist es im Kontext einer Transition empfehlenswert, dass das neue Teammitglied in der Driver-Rolle beginnt. Anstatt also nur passiv zuzuschauen, kommt er aktiv ab der ersten Minute ins Handeln.

    Da ein großer Wissens- und ein für das konkrete System Erfahrungsunterschied vorliegt, ist es für das Mitglied des alten Teams wichtig, immer wieder Kontext zu vermitteln, besonders als Navigator. In manchen Fällen lohnt es sich, die Pairing-Session an einem Whiteboard zu beginnen oder einen gemeinsamen Blick in die (hoffentlich existente) Systemdokumentation zu werfen.

    Eine interessante Alternative zu Pair-Programming ist Mob-Programming. Dabei arbeitet das ganze Team (oder zumindest Teile davon) gemeinsam an einem Arbeitsplatz. Eine Person ist der Driver, alle anderen sind Navigator. Mob-Programming kann gerade am Anfang der Transition als Teil eines initialen Wissenstransfers unglaublich hilfreich sein.

    Test-Driven-Development

    Beim Test-Driven-Development (TDD) geht es nicht, wie häufig geglaubt wird, nur darum, eine hohe Testabdeckung mit Unit-Tests zu erreichen. Die Unit-Tests stellen eher einen sehr wertvollen Seitennutzen dar. Vor allem geht es in eine Entwicklungsmethodik, die folgende vier Schritte umfasst:

    1. Überlege dir für ein klitzekleines Stück Funktionalität (lösbar z.B. in fünf Zeilen) einen Test und ein passendes Design dazu.
    2. Schreibe einen Unit-Test, lass ihn laufen und überprüfe, ob er wirklich fehlschlägt. Die Implementierung ist ja noch nicht da!
    3. Schreibe dann deine Implementierung und überprüfe, ob dein Test jetzt erfolgreich durchläuft.
    4. Mache nochmal eine Review auf deinen Code und refaktoriere ihn, falls nötig.

    Die konsequente Anwendung von Test-Driven-Development ist vor allem im Kontext von Transitionen in Verbindung mit Pair-Programming extrem hilfreich. Durch das Schreiben eines Tests vor der eigentlichen Implementierung wird die Intention der Implementierung glasklar formuliert. Das hilft einem Mitglied des neuen Teams, besser zu verstehen, worum es konkret geht. Wir haben eine beweisbare Form von Spezifikation. Zudem wird durch das Arbeiten in kleinen Schritten die Komplexität handhabbarer gemacht, die Änderung ist dem Mitglied des neuen Teams zugänglicher. Das Mitglied des alten Teams übernimmt hierbei natürlich weiterhin die Einordnung in das große Ganze. Zu Beginn könnte z. B. konkret das Mitglied des alten Teams eher Unit-Tests schreiben, während das Mitglied des neuen Teams eher Implementierung für diese Tests schreibt.

    Auch wenn die hohe Testabdeckung nur einen Seitennutzen von TDD darstellt, ist sie bei einer Transition unglaublich wertvoll. Mitglieder des neuen Teams können an bestehendem Code mit deutlich größerer Sicherheit Anpassungen vornehmen, da die bestehenden Unit-Tests schnelles Feedback zur Implementierung geben.

    Retrospektiven

    Ich konnte schon in der Praxis erleben, dass Transitionen nach dem Prinzip „Augen zu und durch“ durchgeführt wurden. Es wird vorab ein fixer Plan über den Ablauf der Transition gemacht, dieser Ablauf wird mehr oder weniger getreu abgearbeitet, unabhängig davon, wie gut oder schlecht tatsächlich der Fortschritt der Transition ist.

    Retrospektiven können hierbei ein wertvolles Mittel sein, um innezuhalten und gemeinsam mit dem Team darüber zu reflektieren, wie die Transition tatsächlich abläuft. Sofern ein Team sowieso im Rahmen ihrer Methodik regelmäßige Retrospektiven macht (wie z. B. bei Scrum), dann kann das Team einige dieser Retrospektiven nutzen, um über die Transition zu sprechen. Wichtig ist dann natürlich, dass der Moderator den Fokus explizit auf die Transition einschränkt, damit dabei diese speziellen Retrospektiven thematisch nicht zu breit werden.

    Für Teams, die noch nicht im Rahmen ihrer Methodik mit Retrospektiven arbeiten, kann dies ein guter Anknüpfpunkt sein, überhaupt mit Retrospektiven zu beginnen. In diesem Fall werden die ersten Retrospektiven sich nur mit der Transition beschäftigen, mit der Hoffnung, dass das neue Team diese wertvolle Praktik auch nach der Transition beibehält.

    Done Done

    Done Done bedeutet, dass ein Team eine klare Vereinbarung darüber getroffen hat, welche Arbeiten zur Fertigstellung einer neuen Funktionalität nötig sind. Die Vereinbarung wird dann explizit gemacht. Bekannt aus Scrum ist hierfür die Definition of Done (DoD). Das reine Aufschreiben reicht aber nicht aus, wichtig ist außerdem das „Sozialisieren“ der DoD. Das bedeutet, dass das Team auch tatsächlich alle ihre Implementierungen gegen die DoD überprüft. Zudem muss die DoD ein lebendiges Artefakt sein. Das Team muss die Möglichkeit haben, über die DoD zu sprechen und sie ggf. auch anzupassen.

    Das Konzept von Done Done hilft vor allem in zweierlei Hinsicht weiter:

    Erstens unterstützt es Mitglieder des neuen Teams dabei, glasklar zu verstehen, welche Tätigkeiten alle nötig sind, um eine Funktionalität fertigzustellen. Dadurch kann verhindert werden, dass Aktivitäten, die das alte Team durchgeführt hat (z.B. die Erstellung einer Systemdokumentation), vom neuen Team fallengelassen werden. Zudem kann eine lebendige DoD auch an die Gegebenheiten des neuen Teams angepasst werden. Dadurch können vor allem kritische Punkte identifiziert werden, die das neue Team womöglich gar nicht leisten kann.

    Zusätzlich hilft Done Done besser zu verstehen, wo die Transition gerade wirklich steht. Das Liefern von produktiver Software, die die Definition of Done erfüllt, ist eine harte Währung, die im Gegensatz zu vielen anderen Methoden nicht so einfach gefälscht werden kann. Bei einem neuen Team dagegen, das bereits Software im Sinne der Definition of Done liefern kann, kann man zumindest mit einem gewissen Optimismus auf den Erfolg der Transition hoffen.

    Ubiquitous Language

    Transitionen finden häufig in einem internationalen Umfeld statt. Babylonische Sprachverwirrung herrscht aber leider häufig nicht nur bei den natürlichen Sprachen, sondern auch bei den Ausdrücken, die Teammitglieder untereinander verwenden.

    Ubiquitous Language, eine Technik aus dem Domain Driven Design, schafft hier Abhilfe. Diese schlägt vor, dass alle Teammitglieder innerhalb eines bestimmten Kontexts sich auf gemeinsame Ausdrücke einigen, die durchgängig verwendet werden. Die Ausdrücke sollten sich dabei aus der fachlichen Domäne, z.B. einem Domänenmodell, ableiten. Angenommen ein Team hat die Aufgabe, aus einer Beschreibung von Musik in XML Notenblätter zu generieren. Die Ubiquitous Language des Teams wird sich dann um Begriffe drehen wie Partitur, Stimme, Notensystem, Notenschlüssel, Notenzeichen usw. Sie wird sich nicht um Begriffe aus XML drehen wie Entitäten, Elemente und Attribute.[1]

    Zu Beginn einer Transition kann keineswegs davon ausgegangen werden, dass alle Personen das gleiche Verständnis von bestimmten Begrifflichkeiten haben. Ein typisches Beispiel ist hierfür der Begriff „Baumuster“, der selbst innerhalb eines Unternehmens eine Vielzahl von Bedeutungen haben kann. Daher sollte es auch einer der ersten Schritte sein, diese gemeinsame Sprache den Mitgliedern des neuen Teams zu vermitteln. Dies hilft ungemein dabei, einen guten Einstieg zu finden und auch später effektiv mit Stakeholdern des Teams zu kommunizieren.

    Ohne die Verwendung einer Ubiquitous Language ist Verwirrung vorprogrammiert. Neue Teammitglieder können mit Begrifflichkeiten des alten Teams wenig anfangen oder – was noch gravierender ist – bringen eine intuitive, aber falsche, Interpretation mit. Das sorgt schon innerhalb des Teams für Missverständnisse, die zu fehlerhaften Implementierungen führen. Mitglieder des alten Teams haben dabei daher die Verantwortung klar zu kommunizieren, wenn von neuen Teammitgliedern Begriffe unscharf oder verwirrend benutzt werden. Des Weiteren wird ohne Ubiquitous Language die Kommunikation mit Anwendern und Stakeholdern massiv erschwert, wodurch Mitglieder des neuen Teams deren Anforderungen nicht sauber nachvollziehen können.

    Fazit

    Die Anwendung der hier genannten Praktiken aus der agilen Softwareentwicklung haben mir in mehreren Transitionsvorhaben gute Dienste geleistet. Diese Praktiken bewähren sich natürlich nicht nur in Transitionen: Sie leisten grundsätzlich einen Beitrag bei der Entwicklung guter Software. Gute Software wiederum lässt sich einfacher an neue Teams übergeben. Man profitiert also zweifach.


    Über den Autor

    Jonathan Frankenberger hat schon während seines Informatik-Studiums gemerkt, dass sich Software mit agilen Methoden meistens besser entwickeln lässt. Nach einem längeren Ausflug in die Wasserfall-Welt arbeitet er seit 2016 wieder agil in unterschiedlichen Rollen, vor allem mit Scrum. Aktuell unterstützt er als Agile Coach Produktteams bei BettercallPaul dabei, „bessere Wege zu erschließen, Software zu entwickeln“. Daneben beschäftigt er sich auch intensiv mit der Frage, wie Organisationen im 21. Jahrhundert aussehen müssen, um Teams eine gute Umgebung bieten zu können.

    [1] Dieses Beispiel ist „The Art of Agile Development“, 2. Auflage 2021, Seiten 329-331, entnommen.