RAD/Ein kurze Geschichte der Softwareprogrammierung (Teil 1) Drei Jahrzehnte lang haben die Entwickler um Struktur gerungen

07.07.1995

Von Reinhold Thurner*

Auch in der Software-Entwicklung gilt: Wer aus der Geschichte nichts lernt, ist dazu verurteilt, sie zu wiederholen. Neue Techniken stehen vor der Tuer. Sie versprechen uns raschere Programmerstellung, bessere Wartbarkeit und Mehrfachverwendung in grossem Stil. Inwieweit sie tatsaechlich einen Fortschritt bedeuten, laesst sich am besten beurteilen, wenn wir sie als vorlaeufigen Endpunkt einer Software-Entwicklungsgeschichte betrachten, und genau das soll in dieser zweiteiligen Retrospektive geschehen.

Wuerden Journalisten ein Zeilenhonorar von 30 Mark erhalten, so koennte sich kein Mensch eine Zeitung leisten. Eine Zeile Softwarecode kostet aber in etwa soviel - und das seit Jahren. Wen wundert es, dass die Frage der effizienten Entwicklung die Gemueter erhitzt, seit Software in groesserem Umfang hergestellt wird?

Schlechtes Image bei den Auftraggebern

Zugegeben, es laesst sich darueber streiten, ob eine Masseinheit wie Kosten pro Zeile etwas Signifikantes aussagt. Einigkeit herrscht jedoch darueber, dass Software-Entwicklung zu teuer, zu langsam und unzuverlaessig ist. Bei den Softwareprofis blaetterte der Lack in den vergangenen Jahren deutlich ab. Wir werden nicht mehr als treibende Kraft der Innovation angesehen, sondern geniessen mittlerweile vielmehr den Ruf, Innovationsverhinderer zu sein. Ob zu Recht oder nicht, tut wenig zur Sache. Wesentlich ist das schlechte Image der Software-Entwicklung bei denen, die sie bezahlen. Und ganz falsch liegen sie damit sicher nicht.

Dabei bemueht sich die Software-Gilde bereits seit fast 30 Jahren darum, mehr Effizienz und Qualitaet zu erreichen. Die Geschichte dieser Anstrengungen zusammenzufassen, ist nicht ganz einfach, denn hier verliefen zunaechst unterschiedliche Entwicklungen parallel zueinander, um sich dann zu vereinen. Die Jahreszahlen sollen lediglich einen ungefaehren Anhaltspunkt bieten. Ueber ihre Exaktheit laesst sich im Einzelfall diskutieren.

Der Begriff "Software Engineering" wurde 1969 bei dem inzwischen beruehmt gewordenen Meeting in Garmisch-Partenkirchen gepraegt. Er bezeichnet den Anspruch, die Software-Entwicklung durch professionelle Verfahren und Werkzeuge entscheidend zu verbessern.

Doch bereits in den 60er Jahren war das Problem der effizienten Software-Entwicklung ein Thema. Im Gegensatz zu anderen vertrat Professor Dijkstra 1965 die Ansicht, Programmieren sei eine "menschliche Taetigkeit", die durch wohldurchdachtes Vorgehen zu eleganten, effizienten und richtigen Anwendungen fuehren koenne. Die Aufgabe der Programmiersprache bestehe darin, ein unmittelbares Abbild dessen zu erzeugen, was wir uns ausgedacht haben.

Boehm und Jacopini lieferten 1966 die Theorie nach, indem sie aufzeigten, dass Anwendungen mit Hilfe strukturierter Programmierung gebaut werden koennen - mit anderen Worten: indem der Entwickler eine begrenzte Anzahl von Steuerungskonstrukten in Anspruch nimmt. Diese Konstrukte haben sich in der Folge als das kleine Einmaleins des Software-Engineering etabliert.

Der Kern der Ueberlegungen besteht nun nicht darin, den Goto-Befehl zu meiden beziehungsweise durch die erwaehnten Konstrukte zu ersetzen. Es geht vielmehr darum, dass die Kosten eines Programms entscheidend davon bestimmt werden, wie gross der Aufwand fuer das Finden und Beheben von Fehlern ist. Durch Testen laesst sich nur zeigen, dass es Fehler gibt, die Kosten werden dadurch jedoch nicht geringer. Die Schlussfolgerung: Kostensenkung und Beschleunigung der Entwicklung laesst sich nicht dadurch erreichen, dass man Fehler schneller findet und korrigiert, sondern dadurch, dass man keine macht.

Der Pseudocode sollte als direktes Abbild des Ablaufs dienen und - im Gegensatz zu Goto-Befehlen - den Sachverhalt der Folge, Auswahl, Wiederholung und Schachtelung direkt im Programmtext sichtbar machen. In die gleiche Richtung zielte die etwa 1968 eingefuehrte Entscheidungstabellen-Technik, die komplexe Zusammenhaenge (M-zu-N-Beziehungen zwischen Bedingungen und Aktionen) direkt abbildet. Um diese Mittel effizient nutzen zu koennen, wurden entsprechende Werkzeuge gebaut: 1970 der Entscheidungstabellen-Generator "Detab/GT", 1972 der Generator fuer strukturierte Programmierung, "Columbus". In Cobol fand die strukturierte Programmierung ihren Niederschlag erst mit "Cobol- 85", das zudem in der Praxis nicht vor 1990 verfuegbar wurde.

Viele Projekte belegen, dass die strukturierte Programmierung tatsaechlich eine unmittelbar richtige Abbildung der Vorstellung auf den Code ermoeglicht - aber eben nur dort, wo diese Technik angewandt wird und dazu auch eine Vorstellung des richtigen Ablaufs im Gehirn des Entwicklers existiert. Und genau hier liegt das Problem. Fuer einfache (kleine) Programme war die Entwicklung einer solchen Vorstellung nicht allzu schwierig. Je umfangreicher und komplexer die Programme jedoch wurden, desto weniger Programmierer waren dazu noch in der Lage.

Ein Projekt unter der Leitung von Harlan Mills sorgte 1973 fuer einiges Aufsehen. Ein Team hatte es fertiggebracht, 83000 Zeilen Code innerhalb von 22 Monaten zu spezifizieren und zu entwickeln - mit einer verschwindend geringen Fehlerrate: Der erste Fehler tauchte erst 20 Monate nach der Einfuehrung auf.

Entscheidende Faktoren bei dem Projekt waren zum einen die Technik (strukturierte Programmierung), zum anderen die Organisation der Ablaeufe (Entwicklungsprozess) und last, but not least das Teamkonzept, demzufolge unterschiedliche Qualifikationen im "Chief Programmer Team" zusammenarbeiteten. Die Erfolgsstory der strukturierten Programmierung ist eine des Teams und nicht nur der Programmier-Cracks. Mills weist in seinem Bericht allerdings darauf hin, dass dieses Verfahren bei Projekten ueber 100000 Zeilen Code nicht anwendbar sei, weil dafuer ein Team als Einheit nicht ausreiche.

Die strukturierte Programmierung loeste also perfekt das Problem des kleinen, ueberschaubaren Softwaresystems - nur waren solche Anwendungen bald nicht mehr gefragt. Die Projekte wurden immer groesser und komplexer, und hier bot die strukturierte Programmierung lediglich begrenzte Hilfestellung.

Gefragt war vielmehr eine lehr- und lernbare Methode fuer die Einteilung eines Programms in beherrschbare Teile - wiederum mit der Absicht, die Fehlerraten zu druecken und auf diesem Weg mehr Produktivitaet zu erreichen. Entdeckt wurde das Programmdesign. Die theoretische Grundlage, den Top-down-Ansatz, beschrieben beispielsweise Miller und Lamond 1973. Um dieses Geruest auszufuellen, wurden unterschiedliche Wege entwickelt, die alle ihre Berechtigung haben.

Einer dieser Wege ist die normierte Programmierung. Unter der Bezeichnung "Standardisierte Programmierlogik" (SPL) beziehungsweise "Normierte Programmierung" (NPG) haben deutsche Spezialisten ein Verfahren entwickelt, das exakt vorschreibt, wie ein Programm aufzubauen ist, das einen Gruppenwechsel verarbeitet. Dabei wurde die Ablaufsteuerung von der eigentlichen Verarbeitung getrennt und letztere in eigenen Gruppenwechsel-Bausteinen durchgefuehrt.

Damit liess sich ein Programm in unterschiedliche Komponenten aufspalten: in die Ablaufsteuerung und je einen Baustein fuer Anfang und Ende pro Gruppe sowie fuer die Satzebene. Ein Programm mit vier Gruppenstufen gliederte sich also in zehn Komponenten und war dadurch leichter handhabbar.

Der Inhalt jedes Bausteins liess sich jetzt nach den Regeln der strukturierten Programmierung schreiben, da er entsprechend klein geworden war. Und wer es je erlebt hat, kann es bestaetigen: Die Gruppenwechsel-Programme laufen nach diesem Verfahren aus dem Stand. Programme mit komplexeren Datenstrukturen lassen sich damit jedoch nicht abbilden.

Ein Ansatz, der fuer eine wesentlich groessere Anzahl von Programmen taugt, ist die Methode von Michael Jackson, "Jackson Structured Programming" (JSP) genannt. Auch bei Jackson bildet die Struktur der Daten den Ausgangspunkt der Ueberlegungen. Das Rezept sieht folgendermassen aus: Man stelle die einzelnen Datenstrukturen als Baeume dar und vereinige diese zu einem gemeinsamen Baum. Er repraesentiert die Steuerung. An seine Knoten haenge man die Operationen. Fertig. Fuer die wichtigen Steuerungsoperationen gibt es klare Regeln: Vorauslesen, Nachlesen der steuernden Files und ausschliessliche Verwendung strukturierter Konstrukte, die sich direkt aus der Grafik ableiten lassen (vgl Abb. 3).

Dieses Rezept beschreibt konkret, was unter "Top-down" zu verstehen ist. Es ermoeglicht, eine klare Vorstellung ueber den Ablauf zu entwickeln und diese dann direkt im Programm abzubilden. Erfahrene JSP-Programmierer waren anderen in puncto Qualitaet und Produktivitaet entsprechend ueberlegen.

Eine Verschmelzung der Jackson-Methode mit der Baustein-Technik der Normierten Programmierung und der Macro-Technik war die Grundlage des 1976 auf den Markt gebrachten "Delta"-Generators. Er fuehrte ein weiteres Konzept fuer die Produktivitaetssteigerung ein - die systematische Mehrfachverwendung. Mit den Sprachmitteln des Generators liessen sich Programmstrukturen (beispielsweise nach JSP) definieren, in die die Programmbausteine (wie bei NPG) eingebettet waren (vgl. Abb. 4).

Neu war, dass sich die Zuordnung des Codes zu den Programmbausteinen beliebig nach Funktionen strukturieren liess. Das fuehrte zu einer weiteren Differenzierung des Programms in Anwendungs- und Standardcode, der aus einer Makrobibliothek in die Bausteine montiert wurde. Mit dieser Technik liessen sich - bei entsprechender Standardisierung - mehr als 80 Prozent des Codes automatisch generieren.

Das System als Ganzes rueckt in den Mittelpunkt

Mit dem Aufkommen der Transaktionsprogrammierung war das zentrale Problem ploetzlich nicht mehr das Programm selbst, sondern das System als Ganzes, seine Aufteilung in Module und die Einhaltung von Schnittstellen. Die grundsaetzliche Frage, wie ein umfangreiches System in Bausteine aufgeteilt werden sollte, trat in den Mittelpunkt des Interesses. Nicht nur die Programme, sondern auch die Systeme wurden immer groesser und weniger ueberschaubar. Die meiste Zeit ging in den fruehen Phasen der Entwicklung verloren, und die am schwersten zu behebenden Fehler waren die, die beim Design gemacht wurden.

Aus diesem Dilemma wurde der Modellierungsgedanke geboren. Die Idee war folgende: Man entwickelt ein Modell des Systems auf hoher Ebene, und ein Werkzeug generiert daraus die Anwendung.

Schon 1975 hatten Constantine und Yourdon ihre Ueberlegungen zur Systemstrukturierung veroeffentlicht. Der erste Schritt bestand in der Modellierung der technischen Loesung: Statt umfangreicher Programme eine Struktur von Modulen mit loser Kopplung, so lautet die Empfehlung, die die beiden Softwaretheoretiker in ihrem Standardwerk "Structured Design" aussprechen. Diese durch "Structure Charts" abzubildende Struktur sollte den Ueberblick ueber die Zusammenhaenge und Schnittstellen erleichtern.

Mit dieser Aufteilung tritt auch erstmals das System und nicht mehr nur das Programm in den Mittelpunkt des methodischen Interesses: Gelingt es naemlich, ein System in einzelne ueberschaubare Module zu zerlegen, so kann Parallelarbeit zur Zeitverkuerzung eingesetzt werden. Die Module sind kleiner und einfacher und lassen sich einzeln testen.

Einen sehr eleganten Beitrag zu diesem Thema leistete wiederum Altmeister Michael Jackson, der eine Modulbildung durch die Co- Routinen-Technik einfuehrte. Ein System wird, ohne Ruecksicht auf Performance, durch eine Kette einfacher Programme dargestellt, die durch sequentielle Datenstroeme verbunden sind. Meist wird erst nach der Realisierung der Anwendungen offenbar, welche von ihnen zu einem einzigen zusammengefasst werden sollen. Bei der "Programm- Inversion" stoert das nicht. Die Implementierung laesst sich auf einfache Weise im nachhinein festlegen, indem die Programme zu Unterprogrammen erklaert und direkt ueber Calls verbunden werden. Ein Anwendungsgenerator stellt dann automatisch den Code um.

Solche Designansaetze geben zwar eine Antwort auf die Frage, wie sich immer umfangreichere und komplexere Systeme in handhabbare Module und Programme aufteilen lassen. Sie stellen jedoch hohe Anforderungen an den Designer, der das System ueberblicken muss, und - als Folge der nun moeglichen Aufteilung auf mehrere Personen - auch an das Projekt-Management.

Antworten schuldig bleibt das Systemdesign jedoch auf die Fragen, welches Ziel das Projekt verfolgen soll und welche fachlichen Loesungen zu waehlen sind. Bereits Anfang der 80er Jahre machten Berichte ueber den Leerlauf in Grossprojekten die Runde, ueber abgestuerzte Grossprojekte renommierter Firmen, Systeme, die nie fertig wurden, und andere, die bei der Einfuehrung scheiterten oder aber keinerlei betriebliche Vorteile brachten.

Ich erinnere mich gern an ein Seminar, das ich 1977 bei Tom de Marco und Ed Yourdon besuchte. De Marco praesentierte die Ideen seines Buchs, das sich mit der Strukturierung der Analyse befasste. Durch Datenflussdiagramme und Funktionsbaeume wird die Aufgabenstellung eines Systems mit dem Benutzer erarbeitet und in "Minispecs" dargestellt. Die strukturierte Programmierung lieferte fuer die Minispecs das adaequate Ausdrucksmittel - den Pseudocode. Yourdon zeigte mit seinen Structure Charts, wie sich diese Vorgaben in ein Systemdesign umsetzen lassen, das die Aufgaben der Module, ihre Schnittstellen und den Datenfluss festlegt. Auch im Bereich des Designs finden wir einen alten Bekannten wieder - Michael Jackson, der mit seinem JSD eine fortschrittliche und originelle Loesung vorstellte: Er schlug vor, den "Entity-Life- Cycle" zu modellieren, also zu beschreiben, was eine Entitaet (heute wuerde man Objekt sagen) in ihrem Leben tut oder was mit ihr getan wird (Nachrichten und Methoden).

Parallel und fast unbemerkt durch die "strukturierte prozedurale Welt" publizierte Peter Chen 1976 seinen grundlegenden Artikel ueber Datenmodellierung und das Entity-Relationship-Modell. Hier spielen nach Jackson erstmals wieder die Daten eine zentrale Rolle - wenn auch isoliert und mit einem viel hoeheren Grad an Strukturierung.

Die Zeit war reif geworden fuer diese Entwicklung: Immer staerker wurden die Systeme ueber die Daten integriert, und immer mehr stellte sich heraus, dass die Datenstrukturen - richtig entworfen - die stabilen Komponenten eines Systems sind, um die sich die Prozesse ranken.

Kaum jemand wollte ernsthaft bestreiten, dass die strukturierten Techniken die Loesung fuer die anstehenden Softwareprobleme bringen koennten. Nur taten sie es nicht in der Breite, die man erwartet hatte. Die strukturierten Techniken wurden zwar von einigen Experten mit grossem Erfolg angewandt, der Durchbruch gelang jedoch nicht. Die Methodiker und Verfahrensingenieure beklagten die Disziplinlosigkeit der Praktiker, deren Mangel an Einsicht und methodischem Arbeiten.

Maschinelle Unterstuetzung fuer Entwicklungsmethoden

Die Erklaerung war bald gefunden: Mit den Methoden erbte der Entwickler auch einen Berg von Papier, den es zu erstellen, zu pflegen, zu verwalten, zu pruefen und zu verteilen galt. Und die Methoden waren anspruchsvoll: Datenflussdiagramme, Datenmodelle, Funktionsdiagramme, Structure Charts, Pseudocode, Dictionaries, und das alles in hierarchischen Strukturen gegliedert. Das war schwierig zu handhaben und in einem Team von Entwicklern kaum zu bewaeltigen.

So wertvoll jede Methode fuer sich genommen war und so schluessig der Ablauf fuer klassische Batch- und Transaktionsprogramme erschien, so schwerfaellig wurde die Handhabung, sobald die Systeme auch nur ein bisschen an Umfang zunahmen. Die Loesung dafuer konnte nur in einer maschinellen Unterstuetzung dieser Methoden liegen.

Gane und Sarson legten bereits 1977 den Grundstein fuer eine maschinelle Unterstuetzung des Schreibens, Zeichnens, Pflegens und fuer die Konsistenzpruefung von Unterlagen. Die ersten CASE-Systeme unter Unix taten sich auf dem Weg in die kommerzielle Welt allerdings schwer. Anfang der 70er Jahre war - vor allem in Grossprojekten - der Ruf nach mehr Ordnung und Kontrolle in den Projekten laut geworden, und die Organisatoren gaben den ersten Anstoss zu Projektabwicklungssystemen. In Grossbritannien existieren die ersten SSADM-Ansaetze, in Deutschland Orgware, in den USA die Standards der Army, die den Entwicklungsprozess in Phasen, Arbeitsschritte und -ergebnisse strukturierten. Die Franzosen gingen mit Merise den Weg, staerker methodische Elemente einzubinden. Das im deutschsprachigen Raum weitverbreitete IFA- Pass verdankte seinen Erfolg der Tatsache, dass die Einfuehrung und Umsetzung in die Praxis mit viel organisatorischem Geschick sichergestellt wurde.

Diese Modelle eines systematischen Projektvorgehens - man sprach bereits von der Softwarefabrik - eignete sich fuer die Loesung bekannter Aufgaben. Je mehr das Projekt aber eigentlichen Entwicklungscharakter annahm und der Zeitdruck eine Rolle spielte, desto schwieriger liess sich das Vorgehen durchhalten. In vielen Firmen verkam es zu einem inhaltsleeren Formalismus, der keinen Bezug mehr zur Realitaet in den Projekten besass.

Das klassische Projektvorgehen nach dem Wasserfallmodell wurde deshalb zunehmend kritisiert. Vorgeworfen wurden ihm Schwerfaelligkeit und mangelnde Anwendbarkeit in zwei immer wichtigeren Bereichen: der Einfuehrung von Standardsoftware und der Anwendung von Sprachen der vierten Generation (4GL).

(wird fortgesetzt)

*Dr. Reinhold Thurner ist Unternehmensberater im schweizerischen Herrliberg. In den 70er Jahren gruendete er das Unternehmen Delta Software, das den gleichnamigen Programmgenerator entwickelte und vermarktete.