System-Management/Verschiedene Wege führen in die moderne IT

Migration von Altsystemen

14.04.2000
Legacy-Programme gehören zum Nachlass vergangener Softwaregenerationen. Allerdings wünschen sich viele Entwickler, dass sie das Erbe nie antreten müssen. Alexander Scheb* beschreibt unterschiedliche Routen, auf denen sich Altsysteme in die moderne DV überführen lassen.

In vielen Betrieben und Verwaltungen finden sich heute noch Softwaresysteme aus alten Großrechnerzeiten. Da sie die heutigen Anforderungen an die IT nur bedingt erfüllen, sind Renovierungsarbeiten das Gebot der Stunde: Die Altsysteme müssen in eine vernetzte Welt mit mehrschichtigen Architekturen überführt werden. Für den Entwickler bedeutet das eine enorme Herausforderung - allerdings kann er sich zwischen verschiedenen Migrationsstrategien entscheiden.

In den Unternehmen nimmt der Wartungsaufwand an den IT-Systemen stetig zu, da die Entwicklungsarbeiten vielfach aus dem Ruder gelaufen sind. So existieren heute Softwaresysteme, die Mängel an den verschiedensten Stellen aufweisen. Meist ist die Bedienung an den Benutzern vorbei entwickelt worden, die technologischen Voraussetzungen sind heute völlig verändert oder die Verbindung der Applikationen untereinander bereitet Probleme. Aber auch gravierende Marktveränderungen können dazu führen, dass Software nicht mehr zeitgemäß ist.

Oft liegt es an der softwaretechnisch schlechten Umsetzung, dass sich Zielvorstellungen meist nicht erreichen lassen. Man verfuhr bei der Weiterentwicklung lieber wie gewohnt und ignorierte inzwischen verfügbare Entwurfsmethoden und Techniken. So erfüllt die Software zwar noch ihre Aufgaben, aber die Wenigsten im Unternehmen wissen noch, wie das Gesamtsystem funktioniert.

Nach Ansicht von Experten sind in Deutschland 80 Prozent der Cobol-Programme monolithisch aufgebaut und unstrukturiert. Dass neue Techniken vielfach nicht berücksichtigt wurden, erweist sich heute als großer Hemmschuh für die DV-Abteilungen. Es haben sich drei Migrationsstrategien herausgebildet, um die modernen Anforderungen zu bewältigen: die komplette Neuentwicklung, eine Konversion und die Kapselung. Dabei hat sich gezeigt, dass eine Migration in Schritten die beste Vorgehensweise ist.

Ist die Situation derart verfahren, dass sich die logische Struktur des Programmcodes nicht mehr durchschauen lässt, kommen IT-Shops um eine Konversion nicht herum. Um dieses Vorgehen so weit wie möglich zu automatisieren, sollte man grundsätzlich ein Care-Tool (Care = Computer Aided Re-Engineering) einsetzen. Es erleichtert das Programmverständnis und führt den Anpassungsprozess fast komplett selbständig aus. Dabei sollte das Care-Tool kompatibel zum verwendeten Case-Tool (Case = Computer Aided Software Engineering) sein. Eine derartige Sanierung sollte man nur vornehmen, wenn das System noch eine ausreichende funktionale Qualität bietet. Damit man sie einschätzen kann, ist jedoch der genaue Überblick über die Strukturen, Abläufe und Daten des IT-Systems eine Grundvoraussetzung.

Das Hauptziel von Care-Tools ist die ordentliche Stukturierung der kompletten Software des Altsystems. So lassen sich bestehende Applikationen an moderne Anforderungen anpassen und die einzelnen Bausteine viel flexibler wieder verwenden, was die Arbeit der Entwickler erleichtert. Die mit den Tools erzielten Einsparungen sind groß, jedoch wird hierbei immer der Punkt erreicht, an dem es auf das Wissen des Entwicklers ankommt. Dies ist in der Regel beim Übergang vom Entwurf zur Analyse der Fall, wobei nachträgliche Analyseinformationen über Datenflüsse, Strukturen und Kontrollflüsse erzeugt werden. Diese Informationen stellt das Care-Tool dann dem Case-Tool zur Verfügung.

Erst jetzt kommt der eigentliche Nutzen der Konversion ins Spiel. Durch die Neustrukturierung lassen sich Vorteile erzielen, die aus der objektorientierten Programmierung (OOP) bekannt sind. Man kann beispielsweise Softwarebausteine zur Erweiterung der Funktionalität alter Anwendungen einsetzen, die andererseits auch für künftige Applikationen wiederverwendbar sind. Bereits erprobte Programmteile können so erneut genutzt werden, was die Stabilität der Gesamtanwendung fördert. Durch aktive Wiederverwendung muss man nur noch Anpassungsarbeiten leisten, wodurch der Entwicklungsaufwand reduziert wird.

Mittlerweile sind sich Experten darüber einig, dass die objektorientierte Technologie die besten Voraussetzungen für die Wartbarkeit und kostengünstigste Weiterentwicklung von Softwaresystemen bietet. Zusätzlich ermöglicht sie, Anwendungen auf einem vernetzten Rechnersystem beliebig zu verteilen. Der Lösungsansatz sieht den schrittweise vorgenommenen Umbau der Altsoftware in eine Umgebung aus gekapselten Dienstleistungen vor. Dazu fasst man die Daten und Funktionen aus der prozeduralen Welt zu Objekten zusammen. Ein Dienst hat somit das alleinige Recht, die Daten zu ändern und zu verwalten. Auf diese Objekte können andere Komponenten wie Clients (Dienstnachfrager) über die dafür vorgesehene Schnittstelle des Dienstes zugreifen.

Die Aufteilung der Daten und Bildung der Dienstkapseln geschieht im Sinne von Geschäftsobjekten und -prozessen aus der objektorientierten Welt. Normalerweise definiert der Entwickler eine Schnittstelle zwischen dem Frontend und dem Bereich, der die mittlere Schicht werden soll. Dann entfernt er den gesamten Code der Benutzerschnittstelle aus der ursprünglichen Applikation und wandelt die Überreste in einen Netzwerkserver um, indem er eine einfache Systemumgebung hinzufügt. Sie wartet auf Anfragen des Clients mit Hilfe eines Netzwerksockets, bearbeitet die Requests, steuert bei Bedarf eine Datenbank an und gibt das Ergebnis an den Client zurück.

Mit wenigen Zeilen Code lässt sich ein Java-Client programmieren. Die Kosten dafür sind auf jeden Fall gerechtfertigt, da das Programm wesentlich flexibler einsetzbar ist. Der Anwender nutzt das Frontend für seine Zwecke gefahrlos über eine Firewall als mittlere Schicht, und die Datenbestände sind weiterhin sicher im internen Unternehmensnetz aufgehoben. Die einzelnen Objekte lassen sich somit leicht auf den betreffenden Schichten unterbringen. Später kommunizieren sie dann durch speziell definierte Schnittstellen miteinander.

Eine einfachere Alternative zur Konvertierung stellt die Kapselung dar. Dadurch kann die Software in ihrer Umgebung ohne aufwändige Transformation wieder verwendet werden. Eine gewisse Anpassung lässt sich dabei jedoch nicht vermeiden, allerdings fällt sie im Vergleich zu anderen Methoden verhältnismäßig gering aus. Aus fachlicher Sicht kommt es darauf an, die bestehenden Anwendungen zu kennen und zu wissen, welche Softwarebausteine und Datenbestände in die neue objektorientierte Architektur passen. Sie werden markiert und für die Kapselung aufbereitet. Dabei fällt der Prozess abhängig vom Gegenstand der Kapselung (Prozess, Transaktion, Programm oder Prozedur) unterschiedlich aus.

Auf den höheren semantischen Ebenen sind die Bausteine größer und deshalb schwieriger zu kapseln. Große Module haben in der Regel komplexe Schnittstellen, die nur aufwändig zu bedienen sind. Dies bedeutet, dass auf der Seite des Client-Programms mehr Arbeit anfällt, eventuell müssen die Client-Klassen um den vorhandenen Baustein herum gebaut werden. Vor allem bei Online-Transaktionen ist es schwierig, alle Vorbedingungszustände herzustellen, damit die Transaktion korrekt verarbeitet wird. Falls die alte Anwendung in einer benutzerspezifischen Umgebung läuft, muss sie zuvor für die verteilte Verarbeitung angepasst werden. Allein dieser Aufwand kann in ein für sich abgeschlossenes Projekt münden.

Auf der unteren semantischen Ebene sind die Bausteine kleiner und leichter zu kapseln, da ihre Schnittstellen nur einen begrenzten Datenumfang haben. Problematisch ist hier jedoch der Zugang zu den zugehörigen Abschnitten des Codes, die oft tief im Inneren der Programme liegen. Um sie in die neue Anwendung einzubinden, muss der Entwickler im Detail wissen, was die Applikation leisten soll. Allerdings wird es sich kaum lohnen, die Abschnitte zu kapseln, wenn sie zu klein sind. Der Aufwand, sie über das Netzwerk aufrufbar zu machen, steht dann in keinem Verhältnis zum Funktionsumfang. In diesem Fall empfiehlt es sich, Abschnitte komplett neu zu schreiben. Von Fall zu Fall muss entschieden werden, was konkret gekapselt werden soll - ein Patentrezept hierfür gibt es nicht.

Häufig ergibt sich die Notwendigkeit zur Kapselung in der Praxis, wenn ein Anwendungssystem mit dynamischen Verbindungen zu anderen Systemen verteilt werden soll. Eine dynamische Verbindung ist vorhanden, wenn ein Programm in einer Anwendung ein Programm in einer anderen Anwendung aufruft oder wenn ein Programm direkt auf die Daten der anderen Applikation zugreift. Bei einer Verlagerung des aufrufenden Systems wird aus dem Aufruf ein entfernter Prozeduraufruf (RPC = Remote Procedure Call) beziehungsweise eine entfernte Methodeninvokation (RMI = Remote Method Invocation). Aus dem direkten Datenzugriff wird ein Aufruf zu einer entfernten Datenzugriffsschicht. Dabei handelt es sich in allen Fällen um eine Datenfernübertragung zwischen Systemen in verschiedenen Umgebungen.

Bei der Einbindung bestehender Software in neue OO-Systeme taucht häufig der Begriff Wrapping auf. Leicht entsteht dabei der Eindruck, dass Wrapping die Lösung schlechthin für das Legacy-Problem darstellt. Das trifft jedoch nicht zu. Ein Objekt-Wrapper bietet Zugriff auf das Altsystem über eine klar definierte Schnittstelle. Die Kapselung gibt nur solche Attribute und Operationen frei, die der Entwickler für seine Arbeit gerade benötigt. Dabei gibt es verschiedene Kapselungsmöglichkeiten.

Von einer Schichtenbildung spricht man, wenn Schnittstellen aufeinander gelagert werden. Beispielsweise lässt sich eine Corba-IDL-Schnittstelle über ein C-API legen, damit man andere Sichten auf die darunter liegende Schnittstelle erhält. Details der internen Schnittstelle bleiben dabei vor der äußeren verborgen. Die Datenmigration lässt sich über eine Zugriffsschicht implementieren, welche die Struktur der vorhandenen Daten hinter der Zugriffsschnittstelle nicht preisgibt. Das neue System erhält die Daten in einer anderen Form, als sie gespeichert sind. Auch das System-Reengineering lässt sich über eine Modulzugriffsschicht verwirklichen, welche die Struktur der vorhandenen Programme verbirgt. Die Funktionen werden in einer anderen Weise, beispielsweise als Methoden für ein Geschäftsobjekt, genutzt.

Die Kapselung stellt die allgemeinste Form des Objekt-Wrapping dar, wobei die Implementierung strikt von der Schnittstelle getrennt wird. Beispielhaft hierfür ist die Corba-Schnittstellenspezifikation, die unabhängig von den aufgerufenen Prozeduren bleibt. Zur Implementierung der Objektarchitektur ist das Wrapping-Prinzip eine Grundvoraussetzung. Die komponentenbasierte Architektur gewährleistet erst den Grad der Flexibilität, der erforderlich ist, damit sich eine Software mehrfach verwenden und anpassen lässt. Das Wrapping schützt dabei die internen Komponenten von den externen Veränderungen ab.

Insgesamt gibt es fünf Wege, um auf existierende Host-Anwendungen zuzugreifen. Dies geschieht entweder durch einen entfernten Prozeduraufruf, mittels einer speziellen Applikationsprogrammschnittstelle, einer CICS-Transaktion, einer Dateiübergabe oder einer Datentabelle. Im Allgemeinen unterscheidet man weiter einzelne Wrapper-Klassen ohne semantischen Inhalt und in mehrfache Wrapper-Klassen mit semantischem Inhalt. Für die Verbindung zu den Legacy-Systemen empfiehlt sich die Verwendung des Brücken-Entwurfsmusters. Die größten Schwierigkeiten der Implementierung dürfte die langsame Geschwindigkeit später sein, denn die Datenübertragung zwischen dem vorgeschalteten Rechner und dem Host bildet nach wie vor einen potenziellen Engpass.

Der Wrapper findet sich in der Regel an dem Ort, wo die Altsoftware liegt. Entweder wird er statisch gelinkt, oder er bindet die aufgerufenen Module zur Laufzeit. Zwischen dem Wrapper und der verteilten Neusoftware findet ein Nachrichtenaustausch statt, wobei in der Regel ein RPC-Mechanismus oder ein ORB (Object Request Broker) für die Vermittlung verwendet wird. In den letzten Jahren hat sich herausgestellt, dass sich ORBs für derartige Aufgaben gut eignen.

Zu Beginn der Migration von Altsystemen setzt man CareTools ein, um die Gesamtumsetzung besser planen zu können. Jedoch können Care-Werkzeuge nicht als Allheilmittel gelten, da es letztlich auf die Erfahrung des Entwicklers ankommt. Wenn keine Case-Tools bei der ursprünglichen Entwicklung verwendet worden sind, können Care-Lösungen ihre speziellen Stärken ausspielen - vorausgesetzt, es liegen ein kompletter Vorgehensplan für die Analyse des Altsystems und eine konkrete Zieldefinition vor. Nur so kann Software aufbereitet werden, die sich noch über einen langen Zeitraum nutzen lässt.

Ist diese Vorgehensweise aufgrund verschiedener Defizite aussichtslos, sollte man eher eine komplette Neuentwicklung anstreben. Hierbei besteht die Möglichkeit, wieder verwendbare Teile des Entwurfs und des Quellcodes zu identifizieren. Sie lassen sich isolieren und in den neuen Programmen als Kapselung einsetzen.

* Alexander Scheb ist Softwareentwickler und freier Autor in Bonn.

WrapperEin Datenbank-Wrapper ist eine Zugriffsschicht zu bestehenden Datenbeständen. Er macht es Client-Anwendungen möglich, auf alte Daten zuzugreifen und dort zu schreiben, zu lesen, zu ändern und zu löschen.

Ein Service-Wrapper kapselt die Systemdienste wie Drucken, Datenfernübertragung, E-Mail und Speicherverwaltung. Damit können Anwendungen diese Dienste nutzen, ohne auf deren interne Eigenschaften eingehen zu müssen.

Ein Applikations-Wrapper ist eine Softwareschicht, über die Batchläufe, Online-Transaktionen und Programme eines bestehenden Anwendungssystems ausgeführt werden können, ohne sie zu verändern. Der Anwender beziehungsweise Client kann die alten Jobs, Transaktionen und Programme als Objekte in die eigene Anwendung einbinden, wobei der Wrapper die Verbindung dafür herstellt.

Ein Funktions-Wrapper ist ein Schnittstellenumsetzer für den Aufruf einzelner Funktionen in bestehenden Programmen. Die alten Programme werden als Objekte und deren Funktionen als Methoden benutzt. In der Regel muss man die Programme zu diesem Zweck angepassen.

Abb.1: Drei Wege

Quelle: Scheb

Abb.2: Verteilte Welt

Mit einem Component-Broker lässt sich die Verbindung von Objekten über Rechnergrenzen hinweg herstellen, um Altsysteme in einer verteilten Welt einzusetzen. Quelle: Scheb

Abb.3: Wrapping-Struktur

Durch die Wrapping-Technik sind Altsysteme weiterhin nutzbar. Dabei gibt es verschiedene Wrapping-Arten. Quelle: Scheb