Cobol-Anwendungen sind besonders kritisch

Re-Engineering beginnt mit dem Verstehen des Programms

26.07.1991

Nach neueren, von der IBM erhobenen Untersuchungsergebnissen besteht die Tätigkeit der Anwendungsprogrammierer fast zur Hälfte darin, zu erweiternde oder zu pflegende Applikationen erst einmal zu verstehen. Insbesondere die in Cobol erstellten Anwendungen machen den Software-Entwicklern hier Schwierigkeiten. Andreas Bereczky* schlägt eine Lösung dieses Problems vor.

Der Bereich des sogenannten Re-Engineering verursacht bis zu 80 Prozent der Kosten, die während der gesamten Lebensdauer eines Programms anfallen. Im wesentlichen besteht das Re-Engineering aus drei Kategorien von Arbeiten: der Korrektur von Fehlern, Anpassung der Programme an eine neue Systemumgebung und der Modifikation der Aufgabenstellung.

Bekanntlich ist kein anspruchsvolles komplexes Programm fehlerfrei. Leider fallen manche Fehler erst nach monate- oder gar jahrelangem Einsatz des Programms auf, wenn etwa erstmals eine besonders ungünstige Konstellation von Eingabedaten vorliegt oder wenn eine Tabelle überläuft, die zu klein dimensioniert wurde. In einem solchen Fall besteht häufig besonderer Termindruck bei den nötigen Änderungen im Programm.

Mit C + + leicht wartbare

Programme entwickeln

Umstellungsarbeiten werden auch dann fällig, wenn die Systemsoftware auf dem neuen, viel schnelleren Rechner doch nicht so ganz kompatibel zum alten System ist. Auch wenn endlich die Umstellung auf ein neues, effizienteres Datenbanksystem beschlossen wurde oder das Programm nun in einer Netzwerkumgebung laufen soll, müssen die Programme angepaßt werden.

Betrieblich verwendete Software hat sich der wandelnden Struktur eines Unternehmens anzupassen. Beschließt etwa die Leitung einer Bank auf ein bestehendes Buchungsverfahren zu ändern, so ist dies in der Regel mit Modifikationen der Software verbunden.

Eine nicht gerade neue Erkenntnis, die aber nicht oft genug wiederholt werden kann: Der Re-Engineering-Phase sollte besondere Aufmerksamkeit beim Erstellen neuer Programmsysteme gewidmet werden. Eine genaue Dokumentation aller Phasen der Programmentwicklung von der Anforderungsanalyse bis zum Test ist eine Vorbedingung für die Kostensenkung bei späteren Erweiterungen und Änderungen. CASE-Tools und moderne Programmiersprachen wie beispielsweise C+ + bieten eine wertvolle Hilfe für die Entwicklung leicht zu wartender Programmsysteme, da sie einen nachvollziehbaren, modularen und erweiterbaren Entwurf von Programmen unterstützen.

Nun besteht aber in der Praxis kaum die Möglichkeit die im Betrieb befindlichen Programmsysteme neu zu entwikkeln, nur um sie künftig besser warten zu können. Wie lassen sich beispielsweise die hohen Re-Engineering-Kosten der unzähligen Cobol-Programme senken, die auf IBM-Mainframes weltweit im Einsatz sind?

Neu entwickeln ist in der Praxis kaum möglich

Nach neueren Untersuchungen, die die IBM durchgeführt hat, entfallen zirka 47 Prozent der Kosten in der Re-Engineering-Phase nur auf den Aufwand zum Verstehen der Programme.

Dafür sind eine Reihe von Umständen verantwortlich: - Die Dokumentation der bestehenden Programme ist oft unzureichend. Häufig war nicht mehr genug Zeit für eine vernünftige Dokumentation, als das Programmsystem erstellt wurde. Die Auswirkungen dieses Mankos machen sich oft erst nach Jahren - dann aber um so gravierender - bemerkbar. Noch schwieriger wird die Situation, wenn spätere Änderungen am Programm nicht dokumentiert wurden, also Dokumentation und Programm nicht übereinstimmen, was leider gar nicht selten ist.

- Die Entwickler des Programmsystems sind nicht mehr verfügbar. Im Betrieb befindliche Applikationen wurden nicht selten schon vor zehn bis 20 Jahren erstellt und haben das Arbeitsverhältnis der ursprünglichen Entwickler bei weitem überdauert. Die Programmentwickler können bei Re-Engineering-Arbeiten also oft nicht mehr befragt werden.

- Cobol unterstützt weder strukturierte, noch modulare oder objektorientierte Programmierung. Dieser bekannte Mangel der Sprache führt zu oft schwer nachvollziehbarer Programmlogik, da der Programmierer zu sehr auf der Ebene der Maschine und zu wenig auf der Ebene des Problems gedacht hat. Bei Re-Engineering-Arbeiten muß aber die Struktur der gegebenen Problemlösung durch den Programmierer erkannt werden. Diese läßt sich bei maschinennaher Programmierung nur mit sehr viel Mühe aus dem Programmcode ablesen.

Ein Werkzeug, das "auf Knopfdruck" eine bestehende Applikation gleich welcher Qualität in ein ordentlich dokumentiertes, strukturiertes und modulares Softwaresystem überführt, wäre sicher das Ziel aller Wünsche. Ein solches Tool wird es aber wohl nie geben, da "inverse Programmierung", also die automatische Ableitung des Problems aus einem maschinennah geschriebenen Programm nicht möglich ist. Re-Engineering wird auf lange Sicht aus der Interaktion zwischen CASE-Tools und Programmierern bestehen, die schrittweise ein mehr oder minder intuitives Verständnis vom Problemlöseverhalten der zu wartenden Applikation entwickeln.

Wodurch kann aber ein Re-Engineering-Tool den Programmierer bei seiner oft mühevollen Aufgabe unterstützen? Da die Dokumentation der vorliegenden Applikation häufig nur unvollständig oder fehlerhaft vorliegt, ist die wichtigste Quelle zum Verständnis eines Programms oft sein Sourcecode.

Maßgeblich für das Verständnis des Quellcodes sind die Strukturen von Kontroll- und Datenfluß. Während der Kontrollfluß beschreibt, welche Paragraphen und Anweisungen des Programms unter welchen Bedingungen in welcher Reihenfolge ausgeführt werden können, beschreibt der Datenfluß die Verwendung und Modifikation der Programmdaten.

Bei vielen Applikationen ist die Struktur auf den ersten Blick leider nur schwer zu erkennen. Eine Quellcode-Analyse eines Cobol-Programms auf den vorliegenden Kontroll- und Datenfluß kann ein geeignetes Tool jedoch automatisch durchführen. Die so gewonnene Information - gespeichert in einer Datenbank beziehungsweise einem Repository - ist dann der Ausgangspunkt für eine modifizierte statische und dynamische Sichtweise des Programms.

Informationen über Daten und Kontrollfluß eines Cobol-Programms können nun beispielsweise für einen sprachorientierten Editor, für ein intelligentes Testwerkzeug oder für ein Dokumentations-Tool verwendet werden. Das hat selbstverständlich Konsequenzen für den geforderten Leistungsumfang solcher Tools.

Was kann ein intelligenter Cobol-Editor leisten? Sicherlich sollte er zunächst die Funktionen eines bekannten Texteditors - etwa ISPF - und eine vertraute Benutzeroberfläche bieten, um die Eingewöhnungszeit zu reduzieren und die Akzeptanz zu erhöhen. Darüber hinaus braucht er Cobol-sensitive Editierfunktionen; er muß die globale Struktur von Cobol-Programmen kennen und beispielsweise ein FlND-Kommando erlauben, das in einfacher Weise alle Calls oder Paragraphennamen findet.

Es ist sicher sinnvoll, wenn Datendefinitionen in "Copy

Books" oder auch der Code eines referenzierten Paragraphen an der jeweiligen Verwendungsstelle eingeblendet werden können und sich der Cursor entlang des möglichen Kontrollflusses im Programm bewegen läßt. Außerdem sollte das Werkzeug bei der Datenfluß-Analyse eine einfache Cursor Positionierung auf alle Definitions-, Verwendungs- und Modifikationsstellen eines beliebigen Datenfeldes erlauben und dabei Alias-Namen für das Datenfeld berücksichtigen. Schon allein dadurch kann der Editor Zeit beim Verständnis einer zu wartenden Cobol-Applikation einsparen. Aber zum Verständnis einer Anwendung gehört nicht nur die statische Sichtung des Source-Codes. Wesentliche Informationen erhält man oft erst durch die Ausführung der Applikation anhand von Testbeispielen. Hier kann ein intelligentes Cobol-Testwerkzeug Hilfe bieten.

Ein solches Tool sollte alle gängigen Programmumgebungen wie TSO Batch, CICS, DB2 und IMS unterstützen. Ferner muß es alle Programmbestandteile - ob in Cobol, Cobol II, Assembler oder Datenbanksprachen geschrieben - bei der Ausführung des Programms im Source-Code verfolgen können.

Der ausgeführte Code sollte dabei an vorgegebenen Breakpoints oder Trace-Stellen angezeigt werden.

Aufgrund der vorher erfolgten Analyse von Daten- und Kontrollfluß könnte es sinnvollerweise auch möglich sein, Breakpoints auf alle Anweisungen zu setzen, die ein spezielles Feld modifizieren. Daten in Feldern sollen an den Breakpoints angezeigt und durch den Programmierer modifiziert werden können. Hilfreich ist es auch, wenn an den Breakpoints Änderungen im Code vorgenommen werden können; so lassen sich die Auswirkungen von Änderungen gleich ermitteln. Diese Änderungen müssen sich aber bei Bedarf auch leicht wie der zurücknehmen lassen, um dem Programmierer Experimente mit dem zu wartenden Programm zu ermöglichen.

Ein besonders heikler Punkt ist die Behandlung von "Abends"; sie dürfen im Testwerkzeug nicht zum Programmabsturz führen. Der Programmierer muß den Programmablauf, der zum Abend führte, im Testwerkzeug zurückverfolgen können, um die eigentliche Fehlerursache zu finden. Die dazu erforderliche Möglichkeit des "Backward Trace" ist natürlich auch in anderen Situationen von Nutzen.

Eine dritte Komponente, die unbedingt zu einem Re-Engineering-Paket gehört, ist ein Tool zur automatischen Dokumentation der zu wartenden Applikation. Hier ist natürlich wieder die Daten- und Kontrollflußanalyse von Nutzen. Sie kann Fragen beantworten wie:

- Von welchen Stellen im Programm wird ein Paragraph oder ein Statement erreicht?

- Auf welche Weise kann ein Paragraph verlassen werden?

- Gibt es etwa Bedingungen, die zu einem "Fallthru" führen?

- Welche Datenfelder werden im Programm definiert, verwendet oder modifiziert? - unter Beachtung von Aliases und direkten oder indirekten Zusammenhängen mit anderen Feldern?

- Gibt es etwa nicht ausführbaren Code, nicht verwendete Daten oder Daten, die vor ihrer ersten Verwendung nicht initialisiert beziehungsweise nach einer Modifikation nicht mehr verwendet werden?

Natürlich sollte ein solches Dokumentationstool verschiedene Inhaltsverzeichnisse und Listings erzeugen können sowie die eine oder andere Software-Metrik unterstützen. Eine derart erstellte Dokumentation hilft nicht nur bei der Überprüfung, ob firmeninterne Standards (etwa keine Verwendung von "Alter Goto") eingehalten wurden. Sie ermöglicht insbesondere auch die Analyse auf logisch zusammenhängende Teile der Applikation, die ausgegliedert und wiederverwendet werden können. Eine solche Wiederverwendung sollte im Rahmen der Programmentwicklung mit CASE-Tools der gleichen Familie erfolgen, so daß Re-Engineering und Software-Engineering zu einer homogenen Gesamtlösung führen.