Altlast-Code bezieht sich auf Softwarecode, der zwar noch seinen Zweck erfüllt, aber mit inzwischen veralteten Technologien entwickelt wurde. Er umfasst Code, der von einem anderen Team oder einer älteren Softwareversion übernommen wurde, sowie Quellcode, der nicht mehr aktiv unterstützt oder gepflegt wird. Dazu gehört auch Code, der mit veralteter Hardware oder Betriebssystemen, ausgemusterten Compilern oder Anwendungsprogrammierschnittstellen (APIs) oder veralteten Programmiersprachen oder Softwareentwicklungsumgebungen geschrieben wurde. Dies hat zur Folge, dass Altlast-Code nicht mehr den neuen Codierungsstandards, den aktuellen Software-Designprinzipien oder der neuesten Rechnerarchitektur entspricht.
In seinem Buch „Working Effectively with Legacy Code“ aus dem Jahr 2004 bietet Michael Feathers eine andere Beschreibung: „Code ohne Tests.“1 Diese Definition von Altlast-Code bedeutet, dass Programmierer nicht überprüfen können, ob der Code funktioniert und den Erwartungen entspricht. Vielen Altlast-Systemen fehlt auch eine angemessene Dokumentation, die für das Verständnis ihres Verhaltens unerlässlich ist. All das macht ihre Erweiterung oder Verbesserung zu einer schwierigen Aufgabe für Entwickler.
Altlast-Code trägt zu technischen Schulden bei, die im Laufe der Zeit durch laufende Wartung „zurückgezahlt“ werden müssen. Hier sind einige häufige Herausforderungen, denen sich Unternehmen bei der Pflege von Altlast-Code stellen müssen:
● Anpassungsfähigkeit
● Kosten
● Leistung
● Skalierbarkeit
● Sicherheit und Compliance
Aufgrund seiner veralteten Struktur ist Altlast-Code mitunter nicht mehr mit modernen Systemen kompatibel oder nur schwer zu integrieren. Eine solche mangelnde Anpassungsfähigkeit kann Innovationen behindern und das Unternehmenswachstum verlangsamen, wodurch Unternehmen möglicherweise ihren Wettbewerbsvorteil verlieren.
Die Wartung von Altlast-Systemen kann teuer sein. Diese Betriebskosten können sich summieren, da die externen Supportgebühren für ältere Software- und Hardwareversionen steigen. Außerdem kann es schwierig sein, Entwickler zu finden, die sich mit veralteten Computerverfahren oder Programmiersprachen auskennen, was seinen Preis hat.
Schwerfällige, monolithische Architekturen führen zu einer hohen Latenz, langsamen Reaktionszeiten und häufigen Ausfällen. Eine solche Leistungsschwäche kann sich negativ auf die Benutzererfahrung auswirken und die Kundenzufriedenheit beeinträchtigen. Darüber hinaus kann sie die Produktivität und Effizienz der Teammitglieder beeinträchtigen, die mit diesen Systemen arbeiten und sie warten.
Veraltete Systeme können unter der steigenden Benutzerlast leiden. Sie haben Schwierigkeiten, einen sprunghaften Anstieg der Nachfrage zu bewältigen und bedarfsgerecht nach oben oder unten zu skalieren. Außerdem erschweren ihre eng miteinander verbundenen Komponenten die Aktualisierung bestehender Funktionen oder das Hinzufügen neuer Leistungsmerkmale.
Der alte Code wird möglicherweise nicht aktiv mit Sicherheitspatches aktualisiert und entspricht nicht den neuesten Sicherheitsstandards, sodass er anfällig für Cyberangriffe und Sicherheitslücken wird. Es kann auch vorkommen, dass Altlast-Systeme nicht den aktuellen Vorschriften entsprechen.
Die Modernisierung von Legacy-Anwendungen erfordert sorgfältige Planung. Hier ist eine 5-Schritte-Methode, die Ihnen hilft, den Prozess zu optimieren:
● die Codebasis verstehen
● Erfolgreiche Arbeitsteilung
● Charakterisierungstests erstellen
● Refactoring, Migrieren oder Neuschreiben
● Testen und Dokumentieren
Der erste Schritt besteht im Verständnis der Codebasis, was in der Regel auch der schwierigste Teil ist. Beginnen Sie mit der Durchsicht aller verfügbaren Dokumente, seien es Anforderungsdokumente, Inline-Code-Kommentare oder Versionskontrollprotokolle wie Commit-Logs oder Change-Logs.
Wenn die Dokumentation nicht ausreicht, versuchen Sie es mit statischen Codeanalyse-Tools, die den Code automatisch untersuchen, ohne ihn auszuführen. Darüber hinaus können Tools zur Codevisualisierung eine grafische Darstellung des Quellcodes erstellen, was dabei hilft, Abhängigkeiten und Interaktionen zwischen Elementen abzubilden.
Sobald die Softwareentwicklungsteams das Altlast-System ausreichend kennen, können sie es in Angriff nehmen. Diese ausufernden Codebasen können überwältigend sein. Deshalb sollten Sie sie in kleinere, besser überschaubare Module unterteilen und jeweils an einem Modul arbeiten.
Tests werden normalerweise zur Überprüfung der Korrektheit des Codes und seines beabsichtigten Verhaltens geschrieben. Charakterisierungstests werden jedoch erstellt, um zu verstehen, was der Code tut und wie er funktioniert. Dies ist nützlich, um den alten Code zu verstehen.2
Für die Modernisierung von Altlast-Code stehen Unternehmen im Allgemeinen drei Optionen zur Verfügung: Refactoring, Migrieren oder Neuschreiben. Sie können auch eine Kombination aus diesen Ansätzen wählen. Bei der Entscheidung über den richtigen Ansatz müssen sowohl das Software-Engineering-Team als auch die Unternehmensleitung einbezogen werden.
Beim Code-Refactoring wird die interne Struktur des Quellcodes verändert, ohne sein externes Verhalten zu verändern oder seine Funktionalität zu beeinträchtigen. Diese kleinen Änderungen führen weniger zu Fehlern und können zu klarem, sauberem Code führen, der besser wartbar ist.
Bei Altlast-Code können die Teams mit kleineren Änderungen für jedes Modul beginnen, z. B. mit der Umbenennung von Variablen, dem Entfernen doppelter oder ungenutzter Methoden und der Standardisierung der Formatierung. Anschließend können sie mit einer logikbasierten Umstrukturierung fortfahren, z. B. große Methoden in kleinere aufteilen, komplexe Bedingungen vereinfachen und Funktionen zwischen Funktionen verschieben, um Abhängigkeiten zu verringern und die Kohärenz zu verbessern.
Die Migration ist ein weiterer Weg zur Modernisierung von Altlast-Code. Dabei wird der gesamte Code oder Teile davon auf neuere Plattformen oder Tech-Stacks migriert, z. B. durch den Übergang von einer monolithischen Architektur zu Microservices oder die Verlagerung von On-Premises in die Cloud. Dabei muss die Kompatibilität mit der Plattform oder dem Tech-Stack geprüft werden und sichergestellt werden, dass die Anbieter während der Migration entsprechende Unterstützung bieten.
Das Umschreiben von Altlast-Code ist oft der letzte Ausweg, denn dabei wird ein völlig neuer Code erstellt, der den alten Code ersetzt. Dies ist an sich ein neues Projekt – ein gewaltiges Unterfangen, für das möglicherweise ein separates Entwicklungsteam erforderlich ist.
Sowohl die Migration als auch das Neuschreiben können bei riesigen Altlast-Codebasen eine gewaltige Aufgabe sein. Daher können Teams die Strategie der „Würgefeige“ in Erwägung ziehen.3 Eine Würgefeige wächst hoch auf der Oberfläche eines Baumes, ihre Wurzeln reichen bis zum Boden und umhüllen den Wirtsbaum langsam mit einem einschnürenden Geflecht, das ihn schließlich zum Absterben bringt.
Bei Legacy-Systemen können Teams winzige Codefragmente schrittweise migrieren oder neu schreiben, bis die gesamte Codebasis auf ein modernes Framework umgestellt oder in einer aktuellen Programmiersprache entwickelt wurde. Die Teams müssen jedoch eine Übergangsarchitektur aufbauen, damit der bestehende und der neue Code nebeneinander bestehen können. Diese Übergangsarchitektur wird dann außer Betrieb genommen, sobald die Migration oder das Umschreiben abgeschlossen ist.3
Wichtig ist, dass Sie den per Refactoring umstrukturierten, migrierten oder neu geschriebenen Code gründlich testen, um sicherzustellen, dass keine Fehler auftreten. Natürlich können Entwickler ihre eigenen Integrations- und Unit-Tests schreiben. Allerdings sollten Sie auch QA-Teams einbeziehen, die Funktions-, Regressions- und End-to-End-Tests durchführen können, um sicherzustellen, dass die Funktionen und Verhaltensweisen einwandfrei sind.
Die Dokumentation ist ein weiterer wichtiger Bestandteil des Modernisierungsworkflows. Dokumentieren Sie Änderungen am Quellcode, sei es durch das Kommentieren des Codes mit Inline-Kommentaren, das Erstellen detaillierter Änderungsprotokolle oder das Verfassen umfassender Architektur- und Designdokumente und anderer technischer Dokumentation.
Verschiedene Tools können dazu beitragen, den Prozess der Modernisierung von Altlast-Code zu beschleunigen und zu automatisieren. Nachfolgend finden Sie einige gängige Tools:
● Statische Code-Analysatoren
● Anwendungen zur Code-Visualisierung
● Frameworks zur Testautomatisierung
● Migrationsplattformen und Toolkits
● Dokumenten-Generatoren
Statische Analysetools können beim Debuggen von Altlast-Code auf Programmierfehler, Qualitätsprobleme und sogar Sicherheitsschwachstellen helfen. Viele Tools zur statischen Codeanalyse unterstützen ältere Programmiersprachen wie C, COBOL, PL/I und RPG. Beispiele für statische Code-Analysetools sind CodeSonar, Klocwork, das Open Source PMD und SonarQube.
Code-Visualizer stellen den Quellcode grafisch dar, um ein besseres Bild seiner Funktionsweise zu vermitteln, insbesondere bei großen oder komplexen Codebasen. Diese grafischen Darstellungen gibt es in verschiedenen Formaten wie Codemaps, Flussdiagrammen und UML-Diagrammen (Unified Modeling Language). Beispiele für Codevisualisierungs-Apps sind u. a. CodeScene, CodeSee und Understand.
Diese Frameworks erstellen und führen automatisierte Tests aus und erstellen Berichte über diese Tests. Beliebte Frameworks zur Testautomatisierung sind Cypress und Selenium für Webanwendungen sowie Appium für mobile Apps.
Diese Plattformen und Toolkits helfen bei der Vereinfachung und Automatisierung von Migrationsabläufen für Altlast-Systeme. Einige wichtige Migrationsplattformen sind AWS Application Migration Service, Azure Migrate, Google Cloud Migration Toolkits, IBM Cloud Transformation Advisor und Red Hat Migration Toolkit for Applications.
Diese Tools generieren automatisch Dokumentation aus Quellcode und anderen Eingabedateien. Beispiele für Tools zur Dokumentgenerierung sind unter anderem Doxygen, Sphinx und Swimm.
Künstliche Intelligenz (KI) kann bei der Modernisierung von Altlast-Code helfen. Generative KI-Anwendungen werden durch große Sprachmodelle (Large Language Models, LLMs) unterstützt, die komplexe oder große Altlast-Codebasen analysieren können.
Bei den folgenden Aufgaben der Modernisierung von Altlast-Code kann generative KI eingesetzt werden:
● Erklärung des Codes
● Code-Refactoring
● Code-Transformation
● Testgenerierung und -dokumentation
Generative KI kann den Kontext und die Semantik älterer Codebasen verstehen. Dadurch ist sie in der Lage, die Logik und Funktion dahinter zu beschreiben und den Code so zu erklären, dass Programmierer ihn verstehen können.
KI-gestützte Tools können Refactoring-Empfehlungen in Echtzeit geben. IBM® watsonx Code Assistant nutzt beispielsweise IBM® Granite-Modelle zur Identifizierung von Fehlern und Optimierungen. Anschließend schlägt es zielgerichtete Korrekturen vor, die mit den etablierten Codierungskonventionen eines Teams im Einklang stehen und so das Refactoring von Code vereinfachen und beschleunigen.
KI-Systeme können Möglichkeiten vorschlagen, den Quellcode einer Altlast-Programmiersprache in eine modernere Sprache zu implementieren. IBM® watsonx Code Assistant for Z beispielsweise kombiniert Automatisierung und generative KI, um Entwickler bei der Modernisierung von Mainframe-Anwendungen zu unterstützen. Zu diesen generativen KI-Funktionen gehören Code-Erklärung für COBOL, JCL und PL/I sowie die Konvertierung von COBOL in Java-Code.
Wie Frameworks zur Testautomatisierung können auch KI-gestützte Programmierassistenten automatisch Tests erstellen. Außerdem können sie Inline-Kommentare erzeugen, um zu dokumentieren, was bestimmte Code-Fragmente oder -Snippets tun.
Wie bei jeder KI-gestützten Anwendung müssen Programmierer auch beim Einsatz von KI zur Modernisierung von Altlast-Code vorsichtig sein. Sie müssen die Ergebnisse auf Richtigkeit überprüfen und alle vorgeschlagenen Änderungen oder Korrekturen testen.
Instana vereinfacht Ihre Cloud-Migration durch umfassende Überwachung und umsetzbare Erkenntnisse.
Nutzen Sie generative KI für eine beschleunigte und vereinfachte Modernisierung von Mainframe-Anwendungen.
Optimieren Sie Legacy-Anwendungen mit Hybrid Cloud und KI-gestützten Modernisierungsservices und -strategien.
1 Nr. 195 – Working Effectively with Legacy Code and AI Coding Assistant – Michael Feders, Tech Lead Journal, 14. Oktober 2024
2 Characterization Testing, Michael Feathers, 8. August 2016
3 Strangler Fig, Martin Fowler, 22. August 2024