Häufig verwandeln sich Cobol-Programme in "strukturierten Mist"

Neuprogrammierung bleibt oft dem Recycling überlegen

09.02.1990

Auch mit dem Begriff Restrukturierung wird mitunter viel Marketing-Schindluder getrieben. Nach den Erfahrungen von Elmar van Nahl* bleibt die Neuprogrammierung von Cobol-Programmen dem Re-Engineering - egal ob manuell oder werkzeuggestützt - überlegen.

Seit Jahren erscheinen immer wieder Ankündigungen zu Werkzeugen, mit denen "Spaghetti-Programme" restrukturiert werden können. Unter Restrukturierung wird die normale Überführung einer netzwerkartigen Programmstruktur in eine wohlstrukturierte Programmstruktur verstanden, also in eine Struktur, die sich aus Bausteinen mit nur einem Eingang und nur einem Ausgang zusammensetzt.

Die Werbung verspricht das Ende aller Softwareprobleme

Das Ziel der Restrukturierung erscheint klar und verständlich: Man nehme einen Jungbrunnen (ein Restrukturierungsprogramm) und werfe ein altes, pflegeaufwendiges, unstrukturiertes Programm hinein; Dann erhält man ein übersichtliches, wohlstrukturiertes Programm, das auch die nächsten fünf Jahre Programmwartung schadlos übersteht. So jedenfalls lauten sinngemäß die Versprechungen der Anbieter von Restrukturierungswerkzeugen.

In einer neueren Ankündigung wird die Behauptung aufgestellt: "Durch die Anwendung unseres Werkzeugs erhalten die Programme sogar die Idealstruktur, was sich mathematisch beweisen läßt." Wenn diese Aussage zutrifft, gibt es auf einen Schlag kein Softwareproblem mehr.

Ein solches Werkzeug könnte auch bei der Neuentwicklung von Programmen eingesetzt werden. Der Programmierer müßte sich nicht mehr um ein strukturiertes Design bemühen, da sich das Werkzeug um diesen Arbeitsschritt zu kümmern hat. Zu jedem Zeitpunkt der Codierung könnte der Programmtext mit dem Werkzeug bearbeitet werden und würde als Ergebnis ein strukturiertes Programm mit der "Idealstruktur" - was immer das auch sein mag, es hört sich gut an - erhalten.

Die Praxis erwies sich als weitaus mühseliger

Unser Unternehmen begann im Jahre 1980 nach Wegen für die Programmierung zu suchen. In diesem Zusammenhang wurde die Restrukturierung erprobt, die wir - da kein maschinelles Hilfsmittel zur Verfügung stand - manuell durchführten. Sie bestand aus folgenden Arbeitsschritten:

Zunächst wurde der Sourcecode in einer Form gekennzeichnet, daß aus ihm ein Programmablaufplan (im folgenden PAP genannt) abgeleitet werden konnte, der ohne Berücksichtigung der Semantik der Ablauffolgen die Steuerung der Verarbeitung eindeutig wiedergab. Dabei erhielten alle angesprochenen Paragraphennamen in der Reihenfolge ihres Auftretens einen Buchstaben (A..Z, AA..AZ, BA...), der sie eindeutig kennzeichnet.

Dann wurden die GOTO- und PERFORM-Anweisungen mit dem Buchstaben des Paragraphen versehen, zu dem verzweigt werden sollte. Außerdem wurden alle Anweisungsfolgen durchnumeriert. Dabei faßten wir solche Anweisungsfolgen, die eine reine Sequenz darstellten, unter einer Nummer zusammen. IF-Abfragen erhielten eine eigene Nummer.

Für den mit Buchstaben und Nummern gekennzeichneten Sourcecode wurde ein PAP gezeichnet, der keine Semantik mehr zeigte. Anstelle der Anweisung/Anweisungsfolge standen dabei Sequenzkästchen mit der vergebenen Nummer gezeichnet. Statt der echten Paragraphennamen wurde ein Konnektor mit dem dafür vergebenen Buchstaben gezeichnet, die vollständige IF-Abfrage wurde durch eine Raute mit der für IF vergebenen Nummer ersetzt. Pfade, die niemals ausgeführt wurden, fanden keine weitere Berücksichtigung.

Als nächster Schritt erfolgte die Zusammenfassung von zusammen-hängenden und überschaubaren Teilen des PAPs und Überführung dieser Teile in wohlstrukturierte Ablauffolgen. Dabei wurde zunächst nicht berücksichtigt, ob die enthaltenen Blöcke in sich wieder wohlstrukturiert sind.

Darauf folgt die Neuzeichnung des PAPs mit den zusammengefaßten Teilen. Dieser Schritt wird zusammen mit dem vorangegangenen iterativ durchgeführt, bis man einen Ablaufplan für eine Steuerung erhält, die nicht weiter restrukturiert werden muß. Das so entstandene Gebilde wird die Hauptsteuerung des restrukturierten Programms. Nach demselben Verfahren erfolgt auch die Restrukturierung der tieferliegenden Blöcke.

Nicht mit Sachlogig an den Sourcecode herangehen

Nun war der Sourcecode aufgrund der restrukturierten Ablauffolgen umzusetzen. Dafür mußten die zusätzlich im PAP eingeführten Schalter in der WORKING STORAGE definiert, die in sich geschlossenen Zweige des PAPs kodiert, kompiliert und getestet werden. Diese Vorgehensweise wird solange wiederholt, bis der Cobol-Code komplett umgesetzt ist. Der Aufwand für diesen Umsetzungsschritt richtet sich nach der Erfahrung desjenigen, der ihn vollzieht.

Wird nach der Umsetzung beim Test eine Abweichung vom definierten Ergebnis festgestellt, so darf in keinem Fall versucht werden, nach sachlogischen Gesichtspunkten in den Sourcecode einzusteigen. Statt dessen muß der seit dem letzten Test restrukturierte Pfad/Zweig im Sourcecode mit dem Ablaufplan verglichen und dabei geprüft werden, ob die Umsetzung formal korrekt erfolgt ist.

Die Durchführung der Restrukturierungsarbeiten lag bei uns in den Händen von erfahrenen Anwendern und Verfechtern der strukturierten Programmierung, die darüber hinaus eine zusätzliche Schulung in Restrukturierungstechniken erhielten. Bei dem Projekt haben wir folgende Erkenntnisse gewonnen:

- Unabdingbare Voraussetzung für eine manuelle Vorgehensweise ist der vorherige Aufbau eines systematischen Testdatenbestandes, da sich bei den umfangreichen Codeänderungen durch die Restrukturierung Fehler einschleichen können, die sonst erst zu spät auffallen. Allerding ist der Aufbau dieses Testdatenbestandes recht aufwendig, da er praktisch für eine Black Box erfolgt - schließlich wird das Programm restrukturiert, weil es keiner mehr versteht. Für diesen Testdatenbestand muß ein ausreichender Test-Abdeckungsgrad bestimmt werden können, was ohne ein Werkzeug kaum möglich ist.

- Eine formale Restrukturierung versetzt den, der sie durchgeführt hat, in die Lage, das Programm von der Steuerung her zu verstehen. Dieses bessere Verständnis resultiert aber nicht aus dem Ergebnis der Restrukturierung, sondern hat seinen Grund in der intensiven Auseinandersetzung mit dem Programm. Derjenige, der sich in einem Programm aufgrund von durchgeführten Änderungen schon etwas auskennt, findet sich nach der Restrukturierung nur sehr schwer zurecht, weil sich das Programm in seiner topologischen Struktur nicht nur stark verändert, sondern auch zu seinem Nachteil verändert hat.

- Diese negativen Änderungen bestehen in einer Verdoppelung des Sourcecodes, ausgelöst durch die Technik der Codeduplikation und der Einführung von einigen Dutzend neuer Schaltern. Diese Schalter werden immer dann benötigt, wenn eine unzulässige Verzweigung aus einem Block heraus erfolgt. In solchen Fällen ist es erforderlich, einen Schalter zu kreieren, damit dieser Block zunächst über den einzigen zulässigen Ausgang verlassen werden kann. Nach dem Blockaustritt erfolgt die Verzweigung dann in Abhängigkeit von der Schalterstellung.

- Spaghetti-Code und nicht selbsterklärender Programmtext sind siamesische Zwillinge. Selbst in den ablauftechnisch übersichtlichen Programmteilen bleibt die Semantik der Verarbeitung weiterhin im unklaren, falls im Programmtext mit unverständlichen Abkürzungen und Bezeichnernamen gearbeitet wird. Erst wenn unverständliche Namen gegen verständliche eindeutige Bezeichnungen ausgetauscht sind sowie eine Beschreibung der Programmbausteine vorgenommen ist, wird das Programm lesbar und verständlich. Daraus resultiert, daß eine formale Restrukturierung ohne nachfolgende semantische Aufarbeitung wertlos ist.

- Die manuelle Vorgehensweise erfordert besonders qualifizierte Mitarbeiter. Diese fühlen sich bei der Altlastensanierung nicht wohl und werden daher sinnvoller bei der "Vorbeugung", sprich Neuentwicklung, eingesetzt.

- Der Zeitaufwand für die Restrukturierung einschließlich der semantischen Aufarbeitung liegt im Bereich des Aufwandes für die Neuprogrammierung. Dort erhält man die Chance, ein später wartbares Programm zu entwickeln. Bei der Restrukturierung dagegen entstehen schwer zu überschauende Programm-Monster.

Die überraschendste Erkenntnis aus der Restrukturierung war, daß ein formal wohlstrukturiertes Programm keine Garantie für ein transparentes und leicht zu verstehendes Programm abgibt. In dieser Zeit wurde bei uns der Begriff "strukturierter Mist" geprägt. Der Grund dafür ist die ablauforientierten Denkweise, in der Programme entwickelt werden. Dabei wird versucht, fachliche Funktionen in eine ablauftechnische Form zu bringen. Diese Vorgehensweise kann nicht zu natürlichen strukturierten Ablauffolgen führen, weil die Basis nicht natürlich ist.

Keine Lösungstechniken für Erkennungsprobleme

In den Funktionen folgen Daten in einer Weise aufeinander, die real nicht vorkommt. Dadurch sieht sich der Programmierer fortwährend mit sogenannten Erkennungsproblemen konfrontiert, für deren Lösung er die erforderlichen Techniken nicht kennt. So behilft er sich mit der Schaltertechnik, die zur Folge hat, daß man sich an vielen Stellen im Programm Verarbeitungszustände merken muß, um sie an anderer Stelle richtig fortzusetzen. Programme, die so entstanden sind, bleiben selbst dann schwer zu verstehen, wenn sie mit Struktogrammen dokumentiert werden können.

Im Jahre 1986 wurde, angeregt durch Veröffentlichungen über erfolgversprechende Restrukturierungswerkzeuge, das Thema Restrukturierung erneut aufgegriffen. Es erfolgte die Testinstallation eines Werkzeugs. Vorteilhaft war, daß wir auf unsere Erfahrungen aus der manuellen Restrukturierung zurückgreifen konnten.

Restrukturierungstool hatte bedenkliche Nebenwirkungen

Die vom Werkzeug identifizierten Hauptverarbeitungszweige wurden durch eine ebenfalls von ihm generierte, dem eingegebenen Programm übergeordnete Steuerleiste, aufgerufen. Die Verzweigungen von der Steuerleiste zum Programm und vom Programm zur Steuerleiste erfolgen über zusätzlich generierte Schalter. "GOTO"-Anweisungen werden durch "PERFORM ... THRU" ersetzt. Die Programmstruktur wird dahingehend verändert, daß nur noch voneinander unabhängige Paragraphen vorhanden sind.

Es hat sich gezeigt, daß die maschinelle Restrukturierung in einem Bruchteil der Zeit durchgeführt werden kann, die man für die manuelle Vorgehensweise benötigt. Mit dem erstellten Code haben wir folgende Ergebnisse erzielt:

- Im Paragraphenkopf wurden Rückverweise auf die aufrufenden Paragraphen eingefügt.

- Die Art der Restrukturierung war unklar und entsprach keinem bekannten Verfahren. Die Vorgehensweise des Tools in bestimmten Fällen konnte darüber hinaus weder durch Fragen an den Vertreiber noch durch die Unterlagen geklärt werden.

- Kommentare des Originalprogramms können nach der Bearbeitung durch das Werkzeug aufgrund der veränderten Struktur bedeutungslos oder unsinnig werden.

- Die vom Werkzeug durchgeführte Numerierung der Paragraphen führt nicht zu einem besseren Verständnis der Programmstruktur.

- Die Bearbeitung des Programms durch das Werkzeug erforderte einen enorm hohen CPU-Bedarf (für 11 000 Statements zirka 15 Minuten auf einer IBM 3091).

- Das Werkzeug ist nicht in der Lage vorhandene wohlstrukturierte Programmteile zu erkennen und sie in ihrer vorliegenden Struktur zu belassen.

Bedingt durch diese Eigenschaften hatte der Einsatz dieses Tools einige bedenkenswerte Auswirkungen. So wird zum Beispiel eine "saubere" geschachtelte IF-Selektion vom Werkzeug verändert. Wird das vom Werkzeug bearbeitete, restrukturierte Programm unverändert eingegeben, erfolgt eine erneute Bearbeitung mit den ungünstigen Nebenwirkungen:

- Änderung des ZeilenIayout; Blanks werden eliminiert.

- Einzelne Kommentarzeilen verschwinden.

- Die Paragraphen erhalten in jedem Durchlauf eine neue Numerierung, wodurch der Programmierer ständig mit veränderten Programmquellen arbeiten muß.

- Mit jeder Restrukturierung wächst der Quellcode und damit die Compile-Zeit.

Insgesamt lieferte die maschinelle Restrukturierung noch weniger brauchbare Ergebnisse als die manuelle Restrukturierung. Beide Wege, der manuelle und der maschinelle Weg werden daher nicht weiter verfolgt.

Die Alternative zur Restrukturierung heißt Neuprogrammierung. Bevor man ein solches Projekt angeht, sollten allerdings folgende Fragen beantwortet sein: Welche Programme sind für das betreffende EDV-System lebensnotwendig, welche davon gehören unter die Überschrift "nicht mehr oder nur mit großem Aufwand wartbar" und welche Programme werden regelmäßig geändert?

Einer solchen Selektion halten in der Praxis nur wenige Programme stand. Im Einzelfall muß allerdings noch geprüft werden, welche Informationsquellen in welchem Umfang zusätzlich zum Sourcecode zur Verfügung stehen. In Frage kommen Programmspezifikation, das Systemhandbuch, sonstige Dokumentationen und Wissensträger in den Fach- und EDV-Abteilungen.

In Abhängigkeit von der Quantität und Qualität dieser Informationsquellen wird dann auf der Basis des Sourcecodes die Spezifikation für die

Neuprogrammierung erarbeitet. Als hilfreich hat sich dabei erwiesen, wenn vorweg Satzdefinitionen mit selbstdokumentierenden Bezeichnernamen gegen die bestehenden ausgetauscht werden und eine Umsetzung der Namen "alt - neu" stattfindet. Dann muß der Sourcecode schrittweise analysiert werden.

Die jeweils analysierten Programmteile werden so aufbereitet (durch Kommentare und weitere selbstdokumentierende Namen für Bezeichner, deren Semantik gerade neu erkannt wurde), daß sie bei einer erneuten Ablaufverfolgung leicht verständlich gelesen werden können. Am Ende gibt es drei wesentliche Ergebnisse:

1. Die Verarbeitungsaufgaben des Programms sind vollständig beschrieben. . 2. Mindestens ein Mitarbeiter kennt das alte Programm in- und auswendig.

3. Der Sourcecode des alten Programms ist in einen verständlichen Zustand gebracht worden.

Aus diesen Ergebnissen könnte man schließen, daß sich eine Neuprogrammierung erübrigt. Dieser Schluß wäre aber falsch, da ein Problem immer noch nicht gelöst ist. Die fachlichen Aufgaben des Programms können jetzt wohl leichter nachvollzogen werden, die Steuerung dieser Aufgaben wird in der Regel aber nach wie vor in einem Zustand sein, der die Wartbarkeit des Programms stark behindert. +