[an error occurred while processing this directive]

Einführung in den Entwicklungszyklus im Rahmen der Lehre des Programmierens. (Entwicklungszyklus), Lektion, Seite 720786
http://www.purl.org/stefan_ram/pub/programmieren_entwicklungszyklus_de ist die kanonische URI dieser Seite.
Startseite

Entwicklungszyklus

Wasserfall

Die Herstellung des Prototyps eines neuartigen Produktes wird als Entwicklung bezeichnet. Die Herstellung eines neuartigen Programmes bezeichnet man also auch als „Programmentwicklung“ oder „Softwareentwicklung“.

Das Wasserfallmodell (Royce, 1960er Jahre) beschreibt eine lineare Abfolge von Entwicklungsschritten.

Wasserfallmodell
.------------------------------. 
| Planung (strategisch, grob) | 
'------------------------------' 


.------------------------------. 
| Analyse (Spezifikation) | 
'------------------------------' 


.------------------------------. 
| Entwurf (Module) | 
'------------------------------' 


.------------------------------. 
| Implementierung | 
'------------------------------' 


.------------------------------. 
| Integration (Test) | 
'------------------------------' 


.------------------------------. 
| Einsatz (Wartung) | 
'------------------------------'

Eine solche Folge kann aber einige Anforderungen der Praxis nicht befriedigen. Es ist beispielsweise nicht vorgesehen, daß Erfahrungen beim Einsatz von Software die Analyse oder Implementierung beeinflussen.

Zyklus

Das Zyklusmodell (Spiralmodell, iterative Vorgehensweise, prototyping ) erlaubt es, zunächst relativ schnell einen ersten Prototyp zu entwickeln, mit dem Erfahrungen gesammelt werden können, die sich dann wieder auf frühere Phasen auswirken können. Die Phasen werden also wiederholt durchlaufen. Erfahrung beim Einsatz können sich beispielsweise auf die Spezifikation auswirken. Erfahrungen beim Testen können die Implementation verändern.

Zyklusmodell
.------------------------------. 
| Planung (strategisch, grob) | 
'------------------------------' 


.------------------------------. 
| Analyse (Spezifikation) |<-----------. 
'------------------------------' | 
| | 
V | 
.------------------------------. | 
| Entwurf (Module) | | 
'------------------------------' | 
| | 
V | 
.------------------------------. | 
| Implementierung |<----. | 
'------------------------------' | | 
| | | 
V | | 
.------------------------------. | | 
| Integration (Test) |-----' | 
'------------------------------' | 
| | 
V | 
.------------------------------. | 
| Einsatz (Wartung) |------------' 
'------------------------------'

Schrittweises Hinzufügen von Fähigkeiten

Nach dem Wasserfallmodell würde man ein Programm, das 3 Anforderungen erfüllen soll, schreiben, indem man 3 entsprechende Fähigkeiten implementiert und testet.

Wasserfall (Ausschnitt)
.-----------------------------------------. 
| Implementierung von 3 Faehigkeiten | 
'-----------------------------------------' 


.-----------------------------------------. 
| Test der 3 Faehigkeiten | 
'-----------------------------------------'

Dabei würde man aber relativ lange programmieren ohne eine Rückmeldung darüber zu erhalten, ob die Fähigkeiten überhaupt funktionieren. Dieser Mangel kann dadurch behoben werden, daß zunächst ein kleineres Programm erstellt wird, das zunächst nur eine Anforderung implementiert. Diese wird dann getestet und erst anschließend wird die nächste Fähigkeit implementiert und getestet.

Zyklus
.-----------------------------------------. 
| Implementierung der 1. Faehigkeit | 
'-----------------------------------------' 


.-----------------------------------------. 
| Test der der 1. Faehigkeit | 
'-----------------------------------------' 


.-----------------------------------------. 
| Hinzufügen der 2. Faehigkeit | 
'-----------------------------------------' 


.-----------------------------------------. 
| Test der 1. und 2. Faehigkeit | 
'-----------------------------------------' 


.-----------------------------------------. 
| Hinzufügen der 3. Faehigkeit | 
'-----------------------------------------' 


.-----------------------------------------. 
| Test der 1., 2. und 3. Faehigkeit | 
'-----------------------------------------'

Dieses Vorgehen kann bei Programmieraufgaben umgesetzt werden, um den Vorgang der Programmierung kontrollierbarer zu machen.

Nach dem Hinzufügen einer Fähigkeit zu einem Programm, sollten alle vorhandenen Fähigkeiten erneut getestet werden, da es sein kann, daß das Hinzufügen einer Fähigkeit eine andere schon zuvor implementierte Fähigkeit beschädigt.

Es soll beispielsweise ein Programm geschrieben werden, das solange Zahlen einliest, bis der Endwert -1 eingegeben wird. Das Programm soll dann die statistischen Kenndaten „Maximum“, „Minimum“ und „Mittelwert“ ausgeben.

Programm zur Berechnung statistischer Kenndaten
*** Programmstart *** 
Bitte natuerliche Zahlen eingeben und mit "-1" beenden! 
?
23 
?
120 
?
5 
?
-1 
Maximum = 120 
Minimum = 5 
Mittelwert = 49,3333333333333333333333333333333 
*** Programmende ***

Beim „Wasserfall“ würde man das Programm nun zunächst vollständig planen, anschließend vollständig schreiben und erst dann testen.

Wasserfall (Beispiel)
.--------------------------------------------------. 
| Implementierung des Einlesens einer Zahlenliste, | 
| der Berechnung von Maximum, Minimum und des | 
| Mittelwertes. | 
'--------------------------------------------------' 


.--------------------------------------------------. 
| Testen des Einlesens einer Zahlenliste, | 
| der Berechnung von Maximum, Minimum und des | 
| Mittelwertes. | 
'--------------------------------------------------'

Da aber hier zu lange eine Rückmeldung fehlt, kann man den Vorgang besser handhaben, in dem man zunächst nur das durch den Wert -1 beendete Einlesen programmiert. Ziel dieser Phase soll eine lauffähiges Programm sein, das solange Zahlen einliest bis -1 eingegeben wird, aber noch keine statistische Auswertung durchführt.

Programm zur Berechnung statistischer Kenndaten (Version 0.1)
*** Programmstart *** 
Bitte natuerliche Zahlen eingeben und mit "-1" beenden! 
?
23 
?
120 
?
5 
?
-1 
*** Programmende ***

Dann wird diese Programm sofort solange getestet, bis es perfekt funktioniert. Erst anschließend wird die nächste Fähigkeit zum Programm hinzugefügt, beispielsweise die Berechnung des Mittelwerts. Danach wird sowohl das Einlesen der Zahlenliste als auch die neu hinzugefügt Berechnung des Mittelwertes wieder ausgiebig getestet, bevor die nächste Fähigkeit hinzugefügt wird.

Programm zur Berechnung statistischer Kenndaten (Version 0.2)
*** Programmstart *** 
Bitte natuerliche Zahlen eingeben und mit "-1" beenden! 
?
23 
?
120 
?
5 
?
-1 
Mittelwert = 49,3333333333333333333333333333333 
*** Programmende ***

Schließlich kann noch die Berechnung von Maximum und Minimum hinzugefügt werden. Das Vorgehen wäre also wie in der folgenden Abbildung.

Zyklus (Beispiel)
.-------------------------------------------------. 
| Implementierung des Einlesens einer Zahlenliste | 
'-------------------------------------------------' 


.-------------------------------------------------. 
| Testen des Einlesens einer Zahlenliste | 
'-------------------------------------------------' 


.-------------------------------------------------. 
| Implementierung der Berechnung des Mittelwerts | 
'-------------------------------------------------' 


.-------------------------------------------------. 
| Erneutes Testen des Einlesens einer Zahlenliste | 
|-------------------------------------------------| 
| Testen der Berechnung des Mittelwerts | 
'-------------------------------------------------' 


.-------------------------------------------------. 
| Implementierung der Max/Min-Berechnung | 
'-------------------------------------------------' 


.-------------------------------------------------. 
| Erneutes Testen des Einlesens einer Zahlenliste | 
|-------------------------------------------------| 
| Erneutes Testen der Berechnung des Mittelwerts | 
|-------------------------------------------------| 
| Testen der Max/Min-Berechnung | 
'-------------------------------------------------'

Bei diesem iterativen Vorgehen muß aber eine Fähigkeit so implementiert werden, daß die Art ihrer Implementation die spätere Erweiterung um eine zusätzliche Fähigkeit nicht verbaut. Das fällt leichter, wenn schon Erfahrung mit Programmierprojekten gemacht wurde. Daher ist auch dieses Vorgehen nicht ganz unproblematisch. Es ist aber insgesamt doch sicherer als der Wasserfall, da die verwendeten kleineren Schritte leichter zu beherrschen sind.

Vom Editor zum Test

Ein Detail des Vorgehens das beim Erlernen des Programmierens besonders oft vorkommt, soll nun noch einmal erwähnt werden. Werden Programme geschrieben, um eine Programmiersprache zu erlernen, so spielt die Analyse des Systems oder die Auslieferung eines Produktes zunächst noch keine große Rolle. Häufig ist das Erstellen einer Programmdatei mit einem Editor, das Parsen und Testen des Programmes.

Zyklus (beim Programmieren)
.--------------------------. 
| Editieren des Quellcodes |<----------------------------.--. 
'--------------------------' \ \ 
| | | 
V | | 
.--------------------------. / | 
| Parsen |--> Parser-Fehlermeldungen --' | 
'--------------------------' | 
| | 
V | 
.--------------------------. / 
| Ausfuehren (Testen) |--> Laufzeit-Fehler ------------' 
'--------------------------'

Quellcode wird vom Compiler oder Interpreter geparst, d.h. gelesen. Dabei meldet der Parser eventuell gefundene Fehler, wie beispielsweise Syntax-Fehler. Der Programmierer wird in diesem Fall den Quellcode überarbeiten, um die Fehler zu beseitigen. Falls vom Parser keine Fehler mehr gefunden werden, dann kann das Programm ablaufen.

Ein Parser kann aber nicht alle Fehler finden. Besonders semantische Fehler, also Fehlverhalten des Programmes, kann er nicht finden, weil er ja nicht weiß, was das Programm machen soll. Der Programmierer muß das Programm nun testen, um zu sehen, ob es sich unter allen Umständen korrekt verhält. Werden dabei Fehler entdeckt, so wird das Programm erneut überarbeitet, um diese zu beseitigen.

Parser-Fehler

Ein Syntax-Fehler in einem Programm, führt oft zu einer Kaskade mehrerer Fehlermeldungen. Der Programmierer sollte daher bei mehreren Fehlermeldungen zunächst nur die erste Meldung beachten. Die Beseitigung ihrer Ursache führt oft auch zum Verschwinden weiterer Fehlermeldungen.

Der Text von Fehlermeldungen kann oft hilfreich und gelegentlich irreführend sein. Beispielsweise kann eine Fehlermeldung "Semikolon fehlt." tatsächlich manchmal durch Hinzufügen eines Semikolons beseitigt werden. Unter Umständen ist aber beispielsweise auch eine zusätzliche Klammer die Ursache dafür, daß der Parser nun ein Semikolon vermißt, so daß die Lösung dann nicht im Hinzufügen eines Semikolons, sondern im Löschen einer Klammer besteht.

In Zeile drei eine Klammer zuviel?
  34, 
12, 
45 )

Die Zeilennummer oder die Stelle an der ein Parser einen Fehler entdeckt muß auch nicht immer die tatsächliche Stelle des Fehlers sein. Es ist auch möglich, daß der Fehler bereits vor dieser Stelle liegt, aber erst später festgestellt wird.

Ein Parser gibt auch manchmal Warnungen  aus. Dies sind Meldungen, die darauf hinweisen, daß ein Teil einer Quelldatei vielleicht ein Fehler sein könnte oder Mängel hat. Manchmal sind Warnungen Hinweise auf tatsächliche Fehler, manchmal ist es auch richtig sie zu ignorieren, wenn ein Programmierer sich sicher ist, daß die beanstandete Stelle im Quelltext tatsächlich so beabsichtigt ist.

Fehlersuche

Wenn ein Programm vom Parser akzeptiert wurde, dann bedeutet das nur, daß es syntaktisch korrekt ist, aber nicht, daß es sich auch wunschgemäß verhält, d.h. auch semantisch korrekt ist. Um dies zu erreichen, bieten sich verschiedene Mittel an:

Reinraumentwurf Es gibt verschiedene Techniken des Entwurfs und der Implementation von Software, die es weitgehend verhindern können, daß Fehler entstehen. Sie sind aber jenseits des Themas dieser Lektion und werden daher hier nicht weiter behandelt.

Glaskastentest Der Programmierer kennt die verschiedenen Situationen, für die im Programm ein bestimmtes Verhalten festgelegt wurde. Beim Glaskastentest werden die verschiedenen Situationen systematisch nachgestellt und es wird untersucht, ob das Programm sich in allen möglichen Situationen richtig verhält.

Schwarzkastentest Der Programmierer hat vielleicht bestimmte Vorurteile oder eingeschränkte Sichtweisen, die dazu führen, daß er bestimmte Situationen sowohl bei der Programmierung als auch beim Testen ausklammert, so daß das Programm sich dann in diesen Fällen nicht richtig verhält und das aber auch beim Test nicht bemerkt wird. Beim Schwarzkistentest wird das Programm von einer dritten Person getestet, die den internen Aufbau des Programms gar nicht kennt. Dadurch kann sie unbefangen Fehler in Situationen bemerken, an die der Programmierer vielleicht gar nicht gedacht hat.

Für die Fehlersuche gilt die folgende goldene Regel.

Wenn der Fehler nicht da ist, wo man ihn sucht, dann ist er woanders.

Diese Regel bringt zum Ausdruck, daß ein Programmierer oft bestimmte Vorurteile darüber hat, wie ein Fehler zustande kommt. Er sucht dann nur an einer bestimmten Stelle, während der Fehler in Wirklichkeit ganz woanders ist. Man sollte also, wenn man einen Fehler nicht findet, auch andere Ursachen als die zunächst vermuteten in Betracht ziehen und die Untersuchung auf andere Programmteile als die zunächst als Fehlerquelle vermutete ausdehnen.

Aufgaben

Gelegentlich kommt es vor, daß ein Programmierer die besten Absichten und Fähigkeiten hat, aber aufgrund eines Mißverständnisses ein falsches Ergebnis liefert, weil er eine Aufgabenstellung übererfüllen will.

Beispielsweise soll eine Programmierer ein Programm schreiben, daß die Summe von Zahlen ausgibt und er gibt gleich auch noch den Mittelwert aus, obwohl das nicht verlangt war.

Wenn ein Mensch die Ausgabe dieses Programmes liest und den Mittelwert nicht braucht, kann er ihn ja ignorieren. Aber wenn ein anderes Programm die Ausgabe weiterverarbeitet und nur die Summe erwartet, dann funktioniert es nicht mehr oder kann mit einem falschen Wert weiterarbeiten, wenn es plötzlich zwei Werte erhält.

Jede zusätzlich Funktion in einem Programm kann auch Fehler enthalten und die Komplexität erhöhen. Daher geht man mit der „Übererfüllung“ auch ein höheres Fehlerrisiko ein.

Ein Vergleich soll klarstellen, wie schädlich eine Übererfüllung sein kann: Jemand bestellt in einer Gaststätte eine „Pizza Frutti di Mare“. Obwohl dies so nicht auf der Speisekarte steht, möchte der Koch besonders „freundlich“ sein und legt auch noch eine Extra-Portion Salami auf die Pizza. Für den Gast, der gar keine Salami ißt und extra deswegen „Pizza Frutti di Mare“ bestellt hat, weil diese keine  Salami enthält, ist die Pizza nun nicht mehr eßbar.

Daher halten wir folgende Regel fest.

Es ist falsch, wenn ein Programm mehr tut als verlangt.

Seiteninformation und Impressum   
Formular für diese Seite betreffende Mitteilungen an den Herausgeber   
Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. slrprd, PbclevtugFgrsnaEnz