embarc logo
embarc logo

Mikado Methode

Falk Sippach Falk Sippach
07.12.2020

Lesezeit: 8 Minuten

Türchen #7 im arcvent(s)kalender 2020

Viele Entwickler haben tagtäglich mit Legacy-Code zu tun. Aber was ist das eigentlich? Für die meisten ist es einfach alter Quellcode oder der Code von jemand anderem? Und was ist mit meinem eigenen Code, an den ich mich schon nach wenigen Tagen nicht mehr erinnern kann. In dem renommierten Buch “Working Effectively With Legacy Code” gibt der Autor Michael Feathers die folgende Antwort:

To me, legacy code is simply code without tests.

Und tatsächlich wird in einem anderen Klassiker, dem Refactoring Buch von Martin Fowler, das Vorhandensein automatisierter Tests als Voraussetzung für das Refactoring genannt. Diese Tests kann man bei Änderungen am Code jederzeit ausführen. So hat man im Erfolgsfall eine gewisse Sicherheit, dass der Code noch wie erwartet funktioniert. Fehlende Tests machen ein Refactoring zwar nicht unmöglich, erschweren es aber ungemein. Leider lassen sich Tests auch nicht mal schnell nachträglich hinzufügen. Denn häufig ist der Quellcode einfach schlecht testbar. Er müsste dann refactored werden, um einfacher Tests schreiben zu können - ein Henne-Ei-Problem.

Aber auch bei vorhandenen Tests kann man von Legacy Code sprechen. Nämlich dann, wenn sie wenig aussagekräftig sind, das falsche testen, dauerhaft fehlschlagen oder die Testabdeckung einfach sehr niedrig ist. Genausogut gibt es auch Code, der trotz fehlender Tests relativ einfach und gefahrlos geändert werden kann. Darum trifft es die folgende Definition von J. B. Rainsberger besser:

Legacy code is valuable code that we feel afraid to change.

Warum will man alten Code denn überhaupt verändern? Da gibt es doch dieses alte Gesetz in der IT: “Never change a running system”? Leider lässt sich das aber nur selten bewerkstelligen. Von Zeit zu Zeit muss man nun mal Fehler korrigieren, neue Funktionen hinzufügen und ggf. Teile der Anwendung optimieren (z. B. aus Performancegründen).

Um mit Legacy Code umgehen zu können, gibt es diverse Ansätze. In diesem Beitrag wollen wir die Mikado Methode genauer unter die Lupe nehmen. Sie hilft gerade bei komplexeren Refactorings dabei, den Überblick zu behalten und in möglichst kleinen und nachvollziehbaren Schritten vorgehen zu können. Das Ziel ist besser les- und wartbarer Code. Um leichter Tests hinzufügen zu können, muss man zudem stark gekoppelte Abhängigkeiten aufbrechen.

Greenfield vs. Brownfield

Auf der grünen Wiese zu starten ist der Traum vieler Entwickler und Architekten. Man kann moderne Technologien wählen, die neueste Version der Lieblingsprogrammiersprache verwenden und muss keine oder nur wenig Rücksicht auf bestehende Systeme nehmen. Leider dauert es meist nicht lange und die grüne Wiese wird schlammig. Viele Projektbeteiligte, zeitliche Einschränkungen, geringe Erfahrung oder auch einfach Nachlässigkeit führen früher oder später zum Brownfield, im schlimmsten Fall sogar in Richtung der berüchtigten Matschkugel (Big Ball of Mud). Und selbst wenn die Software scheinbar fertig und die erste Version live gegangen ist, so muss sie doch weiter gepflegt und erweitert werden. Im schlimmsten Fall ist die Pflege aber so aufwändig, dass das Hinzufügen neuer Funktionen nur schleppend vorangeht. Der Frust bei allen Projektbeteiligten ist vorprogrammiert, insbesondere wenn Artikel und Konferenzen mit den neuen und sowieso viel besseren Tools, Technologien und Praktiken werben. Und selbst wenn man nach einiger Zeit mal wieder auf der grünen Wiese beginnen darf, so wiederholt sich das Spiel. Um Bestandssoftware dauerhaft wartbar zu halten, bedarf es ein hohes Maß an Disziplin, z. B. in Form von automatisierten Tests bzw. hoher Code-Quailität und Pflege mittels kontinuierlichem Refactoring. Und genau dabei kann die Mikado Methode unterstützen.

Möbel rücken

Stellen wir uns folgendes plastisches Beispiel vor. In unserem Wohnzimmer soll die alte Zweisitzer-Couch aus Studentenzeiten gegen eine schicke Sitzmöbel-Landschaft ausgetauscht werden. Im einfachsten Fall trägt man das eine raus und das andere rein - fertig. Meist ist es aber nicht ganz so einfach. Die ursprüngliche Stelle eignet sich aus Platzgründen nicht für die neuen Möbel. Also muss ein anderer Platz im Raum gefunden werden. Aber da steht derzeit noch der Esstisch. Der muss also zunächst an die Stelle des alten Sofas gerückt werden, damit die neue Couch ihren Platz bekommt. Klingt alles soweit logisch, aber was hat das jetzt mit Legacy Code zu tun? Wenn man Code editiert kommt man häufig nicht weiter. Man muss zunächst an einer weiteren Stelle Anpassungen vornehmen, bevor die eigentliche Änderung funktionieren kann. Dann ist man schnell versucht, einfach direkt eine zweite und vielleicht noch dritte oder vierte Baustelle aufzureissen. Manchmal geht es gut. Gerade erfahrene Entwickler können die verschiedenen Code-Stellen noch gut im Kopf jonglieren. Aber häufig verrennt man sich auch und landet in einer Sackgasse. Wenn man das erst nach einigen Stunden oder sogar Tagen bemerkt, ist der Frust groß. Versionsverwaltungssysteme wie Git lassen uns zwar wieder zum Ausgangsstand zurückkehren, die Zeit ist aber verloren und man ist nicht wirklich schlauer geworden.

Grundsätze des Refactorings

Man sollte immer in möglichst kleinen, überschaubaren Schritten vorgehen. Zudem gilt es ständig zu prüfen, ob die Software noch korrekt funktioniert (z. B. regelmäßig Tests ausführen). Das klappt bei einem begrenzten Kontext noch sehr gut. Bei komplexeren Systemen fällt es aber deutlich schwerer, den Überblick zu behalten. Die Mikado Methode unterstützt durch ihr sehr strukturiertes Vorgehen. So lassen sich blockierende Elemente ermitteln, analysieren (altes Sofa raus, Esstisch umstellen) und letztlich umbauen, damit die neue Couch ihren finalen Platz findet.

Mikado Methode im Detail

The Mikado Method can help you visualize, plan, and perform business value–focused improvements over several iterations and increments of work, without ever having a broken codebase during the process. (Ola Ellnestam, Daniel Brolund: “The Mikado Method”)

Die Vorgehensweise lässt sich dabei auf die folgenden vier Schritte reduzieren, wobei sich die Schritte zwei bis vier typischerweise mehrfach wiederholen.

Vorgehensweise

Zunächst muss man sich das Ziel setzen, auf das man hinarbeiten möchte. Das ist auch gleichzeitig das Kriterium für einen erfolgreichen Abschluß. Dann versucht man im nächsten Schritt eine Lösung zu finden, welche zum Ziel führen könnte. Da es typischerweise nicht die eine klare Lösung gibt, muss man an dieser Stelle experimentieren und Hypothesen prüfen. Man wird in den meisten Fällen dabei etwas kaputt machen, weil andere Dinge unserer Lösung im Weg stehen. Diese Vorbedingungen gilt es also zunächst zu lösen, bevor wir unser eigentliches Ziel erreichen können. Und da sind wir bei Schritt drei, wir schreiben diese notwendige Vorbedingung auf. Im weiteren Verlauf werden andere Hindernisse auftauchen. Und auch diese Vorbedingungen visualisieren wir, so dass letztlich der Mikado Graph entsteht. Bevor man im nächsten Zyklus der Schritte zwei bis vier die gerade entdeckte Vorbedingung versucht zu lösen, kommt etwas Überraschendes. Man macht alle bis dahin angelaufenen Änderungen rückgängig und stellt den zuletzt funktionierenden Stand wieder her. Und hier unterscheidet sich die Mikado-Methode vom draufgängerischen Refactoring, wo man viele Baustellen gleichzeitig aufreisst und sich immer tiefer in den Schlamassel reitet. Das Zurücksetzen des Programmcodes ist für viele kein einfacher Schritt. Dadurch geht ja quasi die Arbeit der letzten paar Minuten verloren. Das stimmt aber nur zum Teil. Denn durch das Visualisieren des Mikado-Graphen bekommt man einen sehr strukturierten Einblick in das System, es findet ein Wissenstransfer statt. Die notwendigen Änderungen werden zudem genau protokolliert, so dass man die Schritte zu einem späteren Zeitpunkt sehr einfach wiederholen kann.

Denn irgendwann, viele Iterationen und die dabei gefundenen Vorbedingugnen später, lässt sich im Schritt zwei das Experiment erfolgreich abschließen. Damit ist man am Ende des Mikado-Graphen, einem Blatt bzw. Endknoten, angekommen. Ab da muss man nur die vorher notierten Schritte rückwärts nochmals durchführen (Replay), bis man beim ursprünglichen Ziel angekommen ist.

Ablauf

Der aufgebaute Mikado-Graph macht es dem Entwickler dabei sehr leicht, Schritt für Schritt alle vorher in den Experimenten ermittelten Änderungen, abzuarbeiten. Ein Refactoring kann sich übrigens nicht nur über mehrere Stunden, sondern auch Tage und Wochen hinziehen. Bei der Mikado Methode kann man jederzeit die Arbeiten unterbrechen und zu einem späteren Zeitpunkt fortsetzen.

Mikado Graph

Fazit und Einsatzgebiete

Das Arbeiten mit der Mikado-Methode wirkt zwar einerseits etwas umständlich, bringt aber entscheidende Vorteile mit. Man hat trotz der laufenden Änderungen jederzeit ein stabiles System. Dadurch kann man das Refactoring zu jedem Zeitpunkt unterbrechen und später fortsetzen. Durch den klaren Ablauf fällt es zudem leicht, sich auf das Refactoring zu fokussieren. Das Vorgehen ist dabei sehr leichtgewichtig. Man braucht im Grunde genommen nur ein Blatt Papier und einen Stift, um den Graphen zu visualiseren. Dieser Graph ist gleich eine Art von Dokumentation und erleichtet die Kommunikation und Zusammenarbeit zwischen den Projektbeteiligten.

Die Mikado-Methode kann man sehr flexibel und in unterschiedlichen Konstellationen einsetzen:

  1. Architektur im Betrieb verbessern
  2. Brownfield Entwicklung
  3. Refactoring Projekt

Sie eignet sich unter anderem, die Architektur in der laufenden Entwicklung in kleinen Schritten zu verbessern. Dabei kann man im gleichen Git-Branch sowohl neue Features ausliefern und zeitgleich an der Verbesserung der Architektur arbeiten. In der Brownfield Entwicklung geht es darum, die Wartbarkeit der Software hoch zu halten. Hier hilft die Mikado-Methode, die bestehende Code-Qualität gezielt zu verbessern, den Code testbarer zu machen, um Tests hinzuzufügen und somit das Sicherheitsnetz aufzuspannen bzw. zu erweitern.

Im Falle von größeren Umbauarbeiten fährt man typischerweise zweigleisig - ein Branch für das Refactoring und einer für die laufende Weiterentwicklung. Das kann mehrere Monate dauern und endet häufig in einem aufwändigem Merge. Bei der Verwendung der Mikado-Methode ist dieses Vorgehen nicht notwendig. Man kann auch über mehrere Monate der Mikado-Graph aufbauen. Erst ganz am Ende werden die eigentlichen Refactorings abgearbeitet. Die Auswirkungen auf die laufenden Feature-Entwicklung ist damit gering.

Die Mikado-Methode ist ein gutes Hilfsmittel, komplexe Refactorings einfach und nachvollziehbar durchführen zu können. Das strukturierte Vorgehen ermöglicht tiefe Einblicke in das Bestandssystem und fördert den Wissenaustausch. Genau wie bei dem beliebten Spiel kommt man Schritt für Schritt zum Ziel, indem man auf dem Weg dahin alle Hindernisse entfernt.

zum arcvent(s)kalender