Vor kurzem stolperte ich beim Schmökern in einem Buch zum Thema Refactoring über den Begriff „Tactical Forking Pattern“. Nach etwas Recherche fand ich dann auch heraus, was es damit auf sich hat. Diese, in manchen Fällen nützliche Alternative zum normalen Extrahieren von Programmteilen, möchte ich euch hier kurz vorstellen.
Die Ausgangslage
Nehmen wir einmal an, wir haben eine Legacy-Software vor uns. Entwickler*innen kamen und gingen, Dokumentation gibt es keine und wenn doch, dann unvollständig und weit verstreut. Ihr kennt es, ich rede von dem sogenannten „Big Ball of Mud“ (wenn nicht, dann fragt in den Kommentaren danach).
Jedenfalls wurde das Management überzeugt: diese Software muss refactored werden. Die Anwendung soll auf Services aufgeteilt werden und das ganze Konstrukt soll auch in die Cloud, wir sind schließlich modern! Nehmen wir weiterhin an, es gibt auch genügend Entwickler, sodass potenziell mehrere Teams möglich wären. Perfekte Voraussetzungen also?!
Der Auftrag
Der Architekt, der das Refactoring gut durchdacht hat, hat nun die einzelnen möglichen Serviceschnitte identifiziert und euer Team bekommt jetzt die Aufgabe, ein besonders beliebtes Featureset aus der Software herauszulösen und einen eigenen Service dafür zu kreieren. Normalerweise kein Problem, ihr kennt euch damit schließlich aus (Abbildung 1).
Das Problem
Sehr bald merkt ihr aber, dass es nicht ganz trivial ist, das Featureset zu extrahieren. Die Abhängigkeiten ziehen sich durch die komplette Codebasis und überall gibt es harte Verknüpfungen. Bald wisst ihr schon gar nicht mehr, wo ihr mit dem Refactoring ansetzen sollt.
Im Übrigen hat auch noch nie jemand Tests in diesem Projekt gesehen. Wie kann ich mir also sicher sein, dass der Rest der Anwendung nicht bricht, wenn ich hier Code extrahiere?
Eine mögliche Lösung: Tactical Forking
Fausto De La Torre, seines Zeichens Director of Platforms and Cloud Europe bei Thoughtworks, hat ein wenig weiter gedacht. Er überlegte, ob das Pferd nicht von hinten aufgezäumt werden kann. In seinem Blogpost beschreibt er, dass es für ein Service-verantwortliches Team einfacher ist, die alte Anwendung mit allem, was dazu gehört, zu klonen (CI/CD, IaC, …). Anschließend entfernt das Team nach und nach alles, was nicht mehr benötigt wird (Abbildung 2). Bildhauer gehen ähnlich vor, wenn sie ihre Werke erschaffen.
Auf diese Art kann das Team, das den neuen Service verantwortet, die Abhängigkeiten zu dem Legacy-Team reduzieren und eigene Workflows etablieren. Zudem ist es einfacher Code wegzuwerfen, der nicht mehr benötigt wird, als Code zu extrahieren.
Die nötigen Schritte
- Zunächst einmal benötigt man einen Fork der Software mit allen Deployment-Mechanismen (wie Tests, Pipelines, IaC, usw. …).
- Im zweiten Schritt wird ein Routing-Mechanismus benötigt, damit auf beide Teile der Anwendung zugegriffen werden kann.
- Der wichtigste Schritt besteht aus konstantem Refactoring, bis die gewünschte Funktionalität im neuen Service isoliert existiert.
- Am Schluss besteht der Fork als eigenständiger Service neben der alten Anwendung.
Und nun?
Zusammenfassend bietet das Konzept des Tactical Forking eine effektive Möglichkeit, komplexe monolithische Anwendungen in kleinere, leichter zu handhabende Services aufzuteilen. Dies erleichtert Änderungen und das Hinzufügen neuer Funktionen, verbessert die Leistung, Wartbarkeit und Skalierbarkeit von Anwendungen.
Wenn ihr also eine komplexe monolithische Anwendung habt, solltet ihr in Betracht ziehen, sie mithilfe von Tactical Forking in Services aufzuteilen.
Schreibe einen Kommentar