yoshitaka272 - Fotolia
Was ist das Strangler Pattern und wie funktioniert es?
Das Strangler Pattern ermöglicht es Softwareteams, Legacy-Systeme schrittweise in den Ruhestand zu versetzen und Anwendungen zu modernisieren. Wir erläutern die Schritte.
Die Migration von einem Legacy-System (Altsystem) zu einer modernen Anwendungslandschaft erfordert umfangreiche Umschreibungsprozesse für den Code. Doch anstatt das System komplett zu überarbeiten und vom Netz zu nehmen, ist es häufig möglich, ein Muster (Pattern) zu implementieren, das ein Legacy-System schrittweise in den Ruhestand schickt, während neue Funktionen hinzugefügt werden.
Mit diesem von Martin Fowler als strangler pattern (Strangler-Muster) bezeichneten Ansatz werden monolithische Anwendungssysteme – umgangssprachlich als big ball of mud (zu Deutsch großer Schlammball) bezeichnet – schrittweise aktualisiert, während sie weiterhin in der Produktion eingesetzt werden. Im Folgenden werden wir uns ansehen, was das Strangler Pattern ist und wie man es implementiert.
Was ist das Strangler Pattern?
Stellen Sie sich ein Motorrad vor, das zwar funktioniert, aber eine umfassende Überholung vertragen könnte, um es besser laufen zu lassen. Eine Möglichkeit ist, das Motorrad komplett zu zerlegen und monatelang umzubauen, bis es wieder funktioniert. Aber wie sicher sind Sie sich, dass es auch noch läuft, wenn Sie alle Teile ausgetauscht haben? Und was ist, wenn Sie das Motorrad in den nächsten Wochen benutzen wollen, aber nicht können, solange es in der Garage steht?
Die Lösung ist, ein Teil nach dem anderen zu ersetzen, sicherzustellen, dass es wie erwartet funktioniert, und dann zum nächsten Bauteil überzugehen, sobald es fertig ist. Dies bietet zwei Vorteile. Der erste ist, dass Sie das Motorrad wahrscheinlich weiter fahren können, während die Teile nach und nach ausgetauscht werden, anstatt auf den Neuaufbau warten zu müssen. Zweitens: Wenn eine Reparatur oder ein Austausch nicht funktioniert, können Sie das Problem viel leichter identifizieren, da Sie nicht alles auf einmal untersuchen müssen. Am Ende werden Sie ein modernisiertes Motorrad haben, das nie wirklich aufgehört hat zu laufen.
Das Strangler Pattern funktioniert auf ähnliche Weise. Anstatt ein Anwendungssystem komplett zu zerlegen und seinen Code neu zu schreiben, bietet es Entwicklungsteams eine Möglichkeit, Codeabschnitte und Funktionen schrittweise zu aktualisieren, ohne das System komplett abschalten zu müssen. Schließlich werden alle Dienste und Komponenten so umgestaltet, dass sie sich in ein neues Anwendungssystem integrieren lassen, und das Altsystem kann in den Ruhestand gehen.
Das bedeutet, dass der Migrationsprozess als iterativer Prozess abläuft und nicht als komplexes Rip and Replace. Die Entwicklungsteams müssen sich nicht so sehr um die Implementierung einer zweiten Codebasis kümmern, sondern können sich auf die Überarbeitung eines Dienstes oder einer Funktion nach dem anderen konzentrieren. Außerdem entfällt die Notwendigkeit, zwei separate Teams zu bilden – eines, das den alten Code verwaltet, und ein anderes, das den neuen Code verwaltet.
Wie man Strangler Pattern implementiert
Das Strangler Pattern mag auf den ersten Blick komplex erscheinen. Wenn Sie jedoch das richtige Verfahren befolgen, ist es eigentlich recht einfach zu implementieren.
Das folgende Diagramm veranschaulicht die Schritte, die zur Implementierung des Strangler Pattern gehören:
Eine der wichtigsten Komponenten des Strangler Pattern ist das facade interface (Fassadenschnittstelle), die als Hauptinteraktionspunkt zwischen dem Legacy-System und den externen Anwendungen und Systemen dient, die es aufrufen. Wenn sich der Code in einem einzigen Modul befindet, das mehrere Dienste eng miteinander verknüpft, können externe Systeme nicht erkennen, welche Codeblöcke mit einer bestimmten Funktion verbunden sind, was die Antwortzeiten verlangsamt und es praktisch unmöglich macht, genaue Tests für einzelne Dienste durchzuführen. Genau dieses Problem löst die Fassade.
Die Fassadenschnittstelle hilft externen Anwendungen und Systemen dabei, den mit einer bestimmten Funktion verbundenen Code zu identifizieren und den zugrunde liegenden Code des Legacy-Systems zu verschleiern. Um dieses Problem zu lösen, wird mit dem Strangler Pattern eine Fassadenschnittstelle geschaffen, die Entwickler dabei unterstützt, diese einzelnen Dienste und Funktionen aus dem Monolithen herauszulösen. Letztendlich wird der Code hinter der Fassade schrumpfen, wenn die Entwickler neuen Code schreiben, testen und bereitstellen.
Das Strangler Pattern in der Praxis
Beispiel 1: Objektorientierte Programmierung
Eine einzelne Klasse, die Tausende oder Zehntausende von Codezeilen enthält, wird manchmal als Gottklasse oder Gottobjekt (god class) bezeichnet. Die Änderung dieser Art von Klasse ist oft einer der schmerzhaftesten Teile von Code-Aktualisierungsprojekten. Da diese Klassen über den Methoden stehen, kann jede Methode auf Variablen zugreifen und diese möglicherweise ändern, für die sie eigentlich nicht vorgesehen war. Das bedeutet, dass eine Änderung an einer Stelle unbeabsichtigte Folgen an anderer Stelle haben kann.
Um das Strangler Pattern auf ein objektorientiertes System anzuwenden, bündeln Sie alle Variablen in objektbasierten Datenstrukturen. Wenn Sie einen Teil des Codes, der mit einer bestimmten Funktion verbunden ist, ändern müssen, speichern Sie diesen Code in dem Objekt, das auf die entsprechende Datenstruktur verweist. Implementieren Sie diese Struktur in die Klasse, die Sie für das neue System, auf das Sie migrieren wollen, erstellen, und spiegeln Sie diese Implementierung im Legacy-Code wider. Mit der Zeit werden Programmierer Änderungen am neuen, gut strukturierten Codes vornehmen, und die Klasse wird langsam verfallen.
Beispiel 2: Webanwendungen
Das Strangler Pattern kann traditionelle serverbasierte Java-Anwendungen in dynamische webbasierte Dienste verwandeln. Sie können damit beginnen, indem Sie schrittweise hart kodierte SQL-Anweisungen durch eine Sprache ersetzen, die Webdienste direkt unterstützen und aufrufen kann, wie zum Beispiel JSON. Schließlich wird der alte Java-Code in die neue Sprache refaktorisiert. Sobald die gesamte Anwendung auf Webservices umgestellt ist, können Sie die traditionelle serverbasierte Logik einfach abschalten.
Beispiel 3: Datenbank
Die meisten unternehmenstauglichen Datenbanken arbeiten heute mit Trigger-basierten Mechanismen, die Code als Reaktion auf Ereignisse ausführen und die auftretenden Änderungen automatisch aufzeichnen. Dadurch ist es möglich, ein zweites System zu unterhalten, das diese Ereignisse ebenfalls ausführen und verfolgen kann. Wann immer eine Änderung in Ihrem Altsystem auftritt, konfigurieren Sie Ihr neues System so, dass es diese Änderungen erfasst und Berichte erstellt. Mit der Zeit können Sie diese Ereignisse so ändern, dass sie direkt an das zweite System weitergeleitet werden. Mit der Zeit können Sie die alte Datenbank vollständig aus dem Verkehr ziehen.
Nach vorne blicken
Wenn Sie eine Änderung an schlechten Code oder einem big ball of mud vornehmen wollen, müssen Sie sich überlegen, wie Sie die Änderung wieder herausziehen und an einem besseren Ort einsetzen können. Bei einigen der oben genannten Beispiele müssen Sie Plattformen verschieben, bei anderen nicht. Wenn Sie das oft genug tun, wird eines Tages etwas Neues um das Alte herum wachsen.
Oder Sie machen einfach weiter Patches, die das ganze System jedes Mal ein wenig schlechter machen. Es liegt ganz bei Ihnen.