Melden Sie sich hier an, um auf Kommentare und die Whitepaper-Datenbank zugreifen zu können.

Kein Log-In? Dann jetzt kostenlos registrieren.

Falls Sie Ihr Passwort vergessen haben, können Sie es hier per E-Mail anfordern.

Der Zugang zur Reseller Only!-Community ist registrierten Fachhändlern, Systemhäusern und Dienstleistern vorbehalten.

Registrieren Sie sich hier, um Zugang zu diesem Bereich zu beantragen. Die Freigabe Ihres Zugangs erfolgt nach Prüfung Ihrer Anmeldung durch die Redaktion.

08.02.1985

SollIst-Diskrepanz fahrt zu realitätsfernen Programmen:Industrie erstickt in schwer änderbarem Code

MÜNCHEN (CW) - Junge Programmierer stecken oft in einem Dilemma, wenn sie ihren ersten Job antreten. Einerseits existiert der Wunsch, das Gelernte anzuwenden, andererseits erben die Softwareingenieure häufig Altprogramme. die lediglich gewartet werden sollen. Das hierbei Fehler auftreten, empfindet Harry Sneed, Geschäftsführer der SES GmbH aus Neubiberg, als zwangsläufig. Er fordert deshalb eine stärkere Berücksichtigung der Wartung im Softwareengineering-Prozeß.

Über die Haupttätigkeiten der Software-Entwicklung ist mittlerweile sehr viel geforscht und geschrieben worden. Abgesehen von dem Projektmanagement handelt es sich um die technischen Tätigkeiten

- Anforderungsspezifikation

- Systementwurf

- Programmierung und

- Testen beziehungsweise Verifikation und Validation (Abb. 1)

Bezüglich der Anforderungsspezifikation gibt es nicht nur etliche Methoden wie Sadt, Structured Analysis, Hipo, Jackson Systems Design und der Entity/Relationship Ansatz, sondern auch viele Spezifikationssprachen wie Special, Gipsy, PSL, RSL oder Sofspec (1).

Systementwurfsmethoden sind noch besser erforscht und beschrieben. Dazu gehören Structured Design von Constantine, Warnier's Logical Construction of Programms, Jackson's Structured Programming Technique, Parnas' Modular Design, das Konzept der abstrakten Datentypen und Object Oriented Design. Dafür sind auch reichlich Entwurfstechniken vorhanden. PDL, Pseudo Code, Struktogramme, Petri-Netze und Baumdiagramme sind nur einige der vielen Mittel zur Darstellung von Programmstrukturen. Andere Sprachmittel beschreiben die Datenstrukturen - Mitteln wie Datenbäume, Datennetze, Entity/Relationsship Diagramme und Relationstabellen (2).

Programmierung ist weitgehend eine Frage der Programmiersprache, gekoppelt mit einer vernünftigen Programmierkonvention. Inzwischen haben wir eine breite Auswahl an leistungsfähigen Sprachen - wie ADA und C für Realtime-Prozesse, Pascal und Fortran für technisch-wissenschaftliche Aufgaben, PL/1 und Cobol für die kommerzielle Datenverarbeitung. Ergänzt werden diese Sprachen durch Konventionen für die modulare, strukturierte und normierte Programmierung, Programmiertechniken, die überall akzeptiert und gelehrt werden (3).

Testtechniken sind auch - wenn in der Praxis noch nicht sehr verbreitet - doch in der Literatur dokumentiert und mittlerweile durch Werkzeuge ausreichend unterstützt. Testmethoden wie die funktionsbezogenen, datenbezogenen und ablaufbezogenen Ansätze zur Definition von Testfällen; Testdeckungsmaßstäbe wie Anweisungsdeckung, Felddeckung und Wertdeckung sowie Testmechanismen wie Drivers und Stubs sind hingänglich bekannt. Testwerkzeuge wie Prüfstand, RXVP, Tip und Softest sind jedem zugänglich, der systematisch testen will. Dies ist nur eine Frage der Durchsetzung (4).

Im Gegensatz zu diesen "abgeackerten" Wissensgebieten gleicht das Gebiet der Software-Wartung einem Urwald. Es fehlen nicht nur die Methoden und theoretischen Grundsätze, es fehlt auch an Definition, was Wartung überhaupt ist. Und dies trotz der Tatsache, daß Wartung über 50 Prozent der Software-Ressourcen beansprucht (5) - also mehr als alle anderen Software-Aktivitäten zusammengenommen.

Um so erstaunlicher ist es, daß die Software-Wissenschaftler dieses wichtige Thema bisher vernachlässigt haben. Dies liegt vor allem daran, daß sich das Problem der Wartung an den Hochschulen und Forschungsinstituten kaum stellt. Dort wird der Nutzen von Programmen nur kurzfristig gesehen.

Anders sieht es jedoch in der Industrie aus. Die Industrie erstickt in langlebigem, schwer änderbarem Code. Die Unbeweglichkeit der Programme steht im krassen Widerspruch zu der hohen Beweglichkeit der Umwelt, die die Programme abbilden. Die daraus resultierende Diskrepanz wird allein durch einen hohen Personaleinsatz überwunden. Damit steigen die Wartungskosten zu einem Vielfachen der ursprünglichen Entwicklungskosten. Die DV-Verantwortlichen sind die Leidtragenden dieses Dilemmas.

Swanson definiert vier Funktionen der Software-Wartung (Abb. 2):

- Korrektion

- Anpassung

- Erweiterung und

- Optimierung (6).

Korrektion beinhaltet die Arbeit, die damit verbunden ist, Fehler zu beheben. Es können Fehler sein, die schon bei der Urentwicklung entstanden sind, oder aber solche, die durch die Wartung entstehen. Diese sogenannte "2. Level-Defects" vermehren sich besonders rapide und machen bald die Mehrzahl der Fehler aus. Verursacht werden sie durch die schlechte Konstruktion und mangelhafte Überschaubarkeit der ursprünglichen Version. Dennoch beträgt der Anteil der Korrektionsarbeiten nur rund 24 Prozent des gesamten Wartungsaufwandes. Um diese Kosten zu reduzieren, muß man die Pflegbarkeit der Software erhöhen.

Anpassung umfaßt jene Tätigkeiten, die durch Veränderungen in der Umwelt erzwungen werden. Es handelt sich hier um drei spezifische Arten. Zum einen sind es Variationen der technischen Umgebung, das heißt, zu der Basis-Software - zum Beispiel zum TP Monitor oder zum DB-System. Zum anderen sind es Änderungen in den Benutzerschnittstellen, so in den Bildschirmmasken, Listen oder Austauschbändern. Zum dritten sind es Umwandlungen der Funktionen, die das System ausführt, zum Beispiel Gesetzesänderungen oder andere betriebliche Regelungen. Diese notwendigen Systemanpassungen betragen rund 22 Prozent des gesamten Wartungsaufwandes. Um diese Kosten zu reduzieren, muß man die Anpassungsfähigkeit der Software erhöhen.

Erweiterung bedeutet die funktionale Ergänzung des Systems. Es werden zusätzliche Funktionen eingebaut, die bei der Urentwicklung nicht vorgesehen waren oder die zwar geplant, aber nicht implementiert wurden. Belady und Lehman sprechen hier von Evolution, andere nennen es inkrementale Entwicklung (7). Es ist fraglich, ob man die Erweiterung überhaupt zu der Wartung zählen sollte. Aber diese Arbeit läßt sich nur schwer von den anderen Tätigkeiten trennen. Falls ein Modul angefaßt wird, werden in der Regel Anpassungen, Erweiterungen und Optimierungen in einem durchgeführt, das heißt, die Arbeit selbst bezieht sich auf den Komponenten. Deshalb wird die funktionale Erweiterung zu der Wartung gezählt, obwohl sie keine echte Wartungstätigkeit ist. Die Systemerweiterung macht rund 40 Prozent des gesamten Wartungsaufwandes aus. Um die Kosten der Erweiterung zu reduzieren, muß die Ausbaufähigkeit der Software erhöht werden.

Optimierung umfaßt alle Arbeiten die dazu dienen, Performance oder die Konstruktion des Systems zu verbessern. Es sind Aufgaben wie Tuning und Speicherbedarfsreduzierung, aber auch Aufgaben wie Restrukturierung des Systems mit dem Ziel, die Pflegbarkeit, Anpassungsfähigkeit und Ausbaufähigkeit zu verbessern. Die Optimierungsarbeiten betragen rund 14 Prozent des gesamten Wartungsaufwandes. Um sie zu reduzieren, müßte das System von Anfang an besser konstruiert werden, das heißt mehr Ressourcen in die Urentwicklung investieren.

Bei der Software-Wartung ist die Diskrepanz zwischen "Ist" und "Soll" besonders auffällig. In einer gewöhnlichen Ist-Situation ruft ein betroffener Anwender den zuständigen Entwickler an und fordert ihn mündlich auf, einen Fehler zu korrigieren oder eine Änderung durchzuführen. Möglicherweise wird er ihm einen Schmierzettel mit einigen ergänzenden Notizen zukommen lassen. Der Entwickler nimmt den Antrag an, schaut sich seinen Code am Bildschirm an, ändert einige Zeilen, übersetzt das Programm neu und bittet den Anwender, es auszuprobieren. Der Anwender tut dies auch und stellt fest, daß gar nichts mehr läuft. Dann geht die Sucherei los. Das Programm wird noch mehrmals geändert, ehe es zur Zufriedenheit des Anwenders läuft.

Code und Entwurf divergieren im Lebenszyklus

Inzwischen meldet ein anderer Anwender, daß seine Ausgaben seit der letzten Änderung nicht mehr stimmen. Jetzt fängt der Kreislauf von vorne an. Der Entwickler hatte vor, die Entwurfsdokumentation noch anzupassen, aber angesichts der neuen Probleme kommt er nicht mehr dazu. Der Code wandert immer mehr vom Entwurf ab. Das Fachkonzept stimmt überhaupt nicht mehr. Es wird nur zu historischen Zwecken aufbewahrt. Bald ist der Code so oft geflickt worden, daß der Entwickler sein eigenes Gedankengut nicht mehr versteht. Er möchte es gerne überarbeiten, aber dazu hat er keine Zeit. Die Fehlermeldungen und Änderungsaufträge häufen sich. Die Anwender werden immer ungeduldiger, der Entwickler immer frustrierter. Am Ende bleibt ihm nur noch die Kündigung als Ausweg aus seiner Misere.

Das Soll-Bild der Wartung sieht natürlich ganz anders aus. Die Anwender haben Formulare, mit denen sie Fehler melden und Änderungen beantragen. Diese gehen an ein Wartungssekretariat, wo sie ergänzt und erfaßt werden. Notfälle werden sofort an eine Notdienststelle weitergeleitet. Alle anderen kommen in eine Warteschlange der Anforderungen, die von einem Steuerungsgremium regelmäßig ausgewertet werden.

Die wichtigsten Anforderungen, die auf einmal durchzuführen sind, werden ausgewählt, zu einem Release gebündelt und als gesamter Anforderungskatalog an das zuständige Wartungsteam geleitet. Dort wird als erstes das Fachkonzept geändert und gegen die neuen Anforderungen geprüft.

Wenn es in Ordnung ist, wird als nächstes der Systementwurf angekündigt und gegen das Fachkonzept geprüft. Es wird auch gecheckt, welche Fernwirkung durch die Änderungen ausgelöst werden konnten. Erst wenn die Prüfung gegen das Fachkonzept bestanden und die Frage der Auswirkung geklärt ist, werden die Module selbst entsprechend dem Entwurf geändert beziehungsweise neu generiert. Gleichzeitig werden die Testprozeduren entsprechend angepaßt, so daß die geänderten Module gleich bestätigt werden können. Zuerst werden alle überarbeiteten Parts komplett neu durchgetestet. Danach werden alle betroffenen Programme neu getestet. Dann erst wird das System den Anwendern zwecks eines Abnahmetests übergeben. Inzwischen wird parallel zu den Entwicklungsaufgaben die Benutzerdokumentation fortgeschrieben. Zum Schluß gibt es eine Review der erfüllten Anforderungen sowie ein Review der Software selbst, um zu gewährleisten, daß die Qualität bewahrt wird.

Es versteht sich, daß die erste Vorgehensweise, zuerst billig ist, aber laufend teurer wird. Die zweite Vorgehensweise ist dagegen am Anfang teurer, aber im Laufe der Zeit wird sie immer billiger. Die Frage der richtigen Wartungsmethode ist also eine Frage der Systemlebensdauer sowie eine Frage der Anzahl Anwender. Für Systeme mit vielen Anwendern und einer langen Lebensdauer lohnt es sich auf jeden Fall, die zweite Methode zu verfolgen. Bei solchen Systemen spricht man von "Configuration Management" (8). Bei Systemen, die wenig Anwender haben und die nur kurzlebig sind, lohnt es sich nicht, einen solchen Apparat aufzubauen. Dazwischen gibt es selbstverständlich zahlreiche Variationen. Wichtig ist, daß gleich am Anfang entschieden wird, in welcher Wartungswelt man leben möchte - in der ad hoc umstrukturierten Welt oder in der Welt der strengen Konfigurationsverwaltung.

Fehlerbehebung ohne Fernwirkung erforderlich

Aus der Definition der Wartungstätigkeiten ergeben sich die Ziele der Wartbarkeit. Zum einen muß die Software pflegbar sein, das heißt, es muß möglich sein, Fehler leicht zu lokalisieren und ohne Fernwirkung auf die restliche Software zu beheben. Dies spricht für möglichst kleine Module mit möglichst wenig wohldefinierten Schnittstellen. Es spricht auch für gut durchdachte Ablaufstrukturen im Sinne der strukturierten Programmierung sowie für möglichst einfache Bedienungslogik und symbolischen Konstanten.

Zum zweiten muß die Software anpassungsfähig sein, das heißt, es muß möglich sein, Änderungen an einer Datenstruktur oder an einer Funktion durchzuführen ohne andere Datenstrukturen und Funktionen ändern zu müssen. Die Software muß möglichst entflochten sein. Dies spricht ebenfalls für kleine spezialisierte Module, zum Beispiel Module für die Programmsteuerung, Parts für die Eingabebehandlung, Module für die Ausgabenbehandlung, Module für die Verarbeitung, Module für allgemeingültige Dienstfunktionen und Module für die Datenverwaltung. Am besten hat man im Sinne des "Information Hiding" einen eigenen Modul für jeden DC-Beleg sowie einen eigenen Modul für jede Datei oder logische Datenbank. Wenn der Beleg oder die Datenstruktur sich ändert, braucht man nur den einen Modul anzufassen.

Zum dritten muß die Software erweiterungsfähig sein, das heißt, es muß möglich sein, neue Funktionen einzubauen, ohne ganze Programme neu schreiben zu müssen. Dafür braucht man eine eindeutige Zuordnung von logischen Funktionen zu physischen Modulen sowie eine klare Trennung von logischen und physischen Datenstrukturen. Die Programme sollen auch möglichst einheitlich strukturiert sein, und es muß Übereinstimmung zwischen Code und Entwurfsdokumentation herrschen.

Schließlich, um diesen drei Funktionen dienlich zu sein, müßte das System von Anfang an im Hinblick auf diese Faktoren konstruiert sein. Dies ist aber leicht gesagt. In der Regel ist man bei der Urentwicklung ausschließlich mit dem funktionalen Umfang beschäftigt. Für Qualitätsgesichtspunkte gibt es keine Zeit. Die Qualität läßt sich erst nachträglich in ein Produkt einbauen, erst dann, wenn das Problem der Qualität gelöst ist.

Denn alle Erfahrungen sprechen dafür, daß der Mensch offensichtlich nicht in der Lage ist, beide Probleme auf einmal zu lösen. Knuth notierte, daß alle Programme zweimal geschrieben werden müssen, um die erforderliche Qualität zu erreichen (9). Diese Aussage trifft um so mehr auf komplexe Systeme zu. Sie müssen in mindestens zwei Stufen entwickelt werden - in der ersten Stufe werden die angeforderten Funktionen erfüllt, in der zweiten Stufe wird das System im Hinblick auf die Wartbarkeit restrukturiert und optimiert.

In der Literatur wird oft von "Prototyping" gesprochen ( 10). Das Ergebnis der ersten Stufe könnte als Prototyp bezeichnet werden. Aber hier hinkt der Vergleich zu Prototypen in anderen Ingenieurdisziplinen. Dort ist ein Prototyp ein verkleinertes Modell des endgültigen Produktes zum Zwecke der Planung. Im Falle von Software-Systemen ist dies nicht zutreffend. Die erste Version ist ein unvollkommenes Produkt, mit dem man schon arbeiten kann. Sie hat aber nicht die Eigenschaften, die man sich langfristig wünscht. Die folgende verbesserte Version leistet nicht mehr als die erste. Sie ist nur zuverlässiger, pflegbarer, anpassungs - und ausbaufähiger. Möglicherweise ist sie auch effizienter und benutzerfreundlicher.

Wer also seinen Wartungsaufwand reduzieren will, muß sich mit diesem Zweistufenkonzept abfinden. Es gibt dazu zur Zeit keine echten Alternativen.

Literaturhinweise

(1) Ramamoorthy, C./Yeh, R. Editors: Software Methodology, IEEE Tutorial, IEEE Computer Society, Long Beach, CAL., 1978

(2) Freeman, Pl./Wassermann, A., Editors: Software Design Techniques, IEEE Tutorial, IEEE Computer Society, Los Angeles, CAL., 1983

(3) Hughes, J./Mitchtom, J.: Strukturierte Softwareherstellung, Oldenbourg Verlag, München, 1980

(4) Adrion, W./Branstad, M./Cherniavsky, J.: Validation, Verification and Testing of Computer Software, in ACM Computing Surveys, Vol. 14, Nr. 2, 1982

(5) Parikh, G. /Zvegintzov, N.: Tutorial on Software Maintenance, IEEE Tutorial, IEEE Computer Society, Los Angeles, CAL., 1983

(6) Lientz, B./Swanson, E.: Software Maintenance Management, Addison Wesley Publishing, Reading, Mass., 1980

(7) Belady, L./Lehmann, M.: "The Evolution Dynamics of Large Programms" in IBM Systems Journal, Nr. 3, Sept., 1975

(8) Bryan, W./Chadbourne, C./Siegel, S., Editors: Software Configuration Management, IEEE Tutorial, IEEE Computer Society, Los Angeles, CAL., 1980

(9) Knuth, D.: The Art of Computer Programming, Vol. I ., Fundamental Algorithms, Addison-Wesley Publishing, Reading, Mass., 1968

(10) Patton, R.: "Prototyping - A Nomenclature Problem" in ACM Software Engineering Notes, Vol. 8, Nr, 2, April 1983