Fachkonzept: Programmentwicklung

Das typische Vorgehen zur Entwicklung von komplexen Programmen gliedert sich in fünf Phasen. Diese werden im folgenden kurz erläutert. Um klar zu machen, was gemeint ist, wird das folgende Problem gelöst:

Der Hamster soll seine fünf gesammelten Körner in seinem Lager ablegen.

Ausgangssituation:
Zielsituation:

Problemanalyse

In der Problemanalyse werden alle Fragen geklärt und Probleme analysiert, die mit dem Programm gelöst werden sollen. Bezogen auf den Hamstersimulator könnten das z.B. folgende Fragen sein:

  • Ausgangssituation
    • Wo steht der Hamster? In welche Richtung schaut er? Wie viele Körner hat er im Maul? Wo liegen wie viele Körner? Wie liegen die Mauern?
  • Weg dort hin
    • Was muss der Hamster auf dem Weg zum Ziel hin machen? Wie kommt er zum Ziel? Darf er zwischendurch zurück gehen? Welche Regeln muss der Hamster befolgen?
  • Zielsituation
    • Wo muss der Hamster hin? In welche Richtung soll er schauen? Wie viele Körner soll er im Maul haben? Sollen irgendwo Körner liegen?

Diese Fragen und deren Antworten werden in einem Anforderungsheft festgehalten. Somit kann in den späteren Phasen darauf zurückgegriffen werden.

Im Beispiel ergeben sich folgende Antworten:

  • Ausgangssituation
    • Der Hamster steht auf Kachel (1,1), schaut in Richtung Osten und hat fünf Körner im Maul. Es gibt keine weiteren Körner, die Mauern bilden einen Pfad mit einer Rechtskurve.
  • Weg dort hin
    • Der Hamster muss sich auf Kachel (1,4) rechts rum drehen. Ansonsten muss er nur gerade aus laufen, bis er sein Lager auf Kachel (2,4) erreicht hat.
  • Zielsituation
    • Der Hamster soll auf Kachel (2,4) und nach Süden schauen. Er soll keine Körner mehr im Maul haben und alle Körner sollen auf Kachel (2,4) liegen.

Entwurf

In der Entwurfs-Phase wird versucht, die Fragen schon so zu gruppieren oder zu zerlegen, dass sie für die spätere Implementierung sinnvoll zusammengestellt sind. Hierfür kann man eines der beiden folgenden Prinzipien verwenden:

  • Prinzip der schrittweisen Verfeinerung
    • Minimale Problemlösung - Das Problem wird auf minimale Weise gelöst, also z.B. nur im Ansatz.
    • Problemlösung schrittweise verbessern - Diese minimale Lösung wird schrittweise verbessert und erweitert, um mehr Aspekte des Problems zu lösen. Hierbei wird der Programmcode angepasst.
  • Prinzip der Aufteilung in Teilprobleme
    • Teilprobleme identifizieren - Das Grundproblem wird in mehrere, kleinere Teilprobleme zerlegt.
    • Diese nacheinander lösen - Diese Teilprobleme werden einzeln gelöst.

Außerdem können Lösungsideen oder -ansätze gesammelt werden, die für die Implementierung hilfreich sein können. Auch diese Phase wird im Anforderungsheft dokumentiert.

Für das Beispiel kann man sich für einen der beiden Wege entscheiden.

  • Prinzip der schrittweisen Verfeinerung
    • 1. Schritt: Der Hamster läuft bis zur Rechtskurve.
    • 2. Schritt: Der Hamster läuft bis zur Rechtskurve und dreht sich.
    • 3. Schritt: Der Hamster läuft bis zur Rechtskurve, dreht sich und läuft bis zum Lager.
    • 4. Schritt: Der Hamster läuft bis zur Rechtskurve, dreht sich, läuft bis zum Lager und legt alle Körner ab.
  • Prinzip der Aufteilung in Teilprobleme
    • 1. Teilproblem: Bis zur Wand laufen (einmal bis zur Kurve, einmal bis ins Lager)
    • 2. Teilproblem: Rechts rum drehen
    • 3. Teilproblem: Alle Körner abgeben

Implementierung

Erst in der dritten Phase fängt man an, zu programmieren. Die Ideen aus der Entwurfs-Phase werden implementiert, indem das ausgewählte Prinzip weiter verfolgt wird:

  • Prinzip der schrittweisen Verfeinerung
    • Entwickeln des Programmcodes, danach zurück zum Entwurf - Der Programmcode wird so implementiert, dass das Minimalproblem gelöst ist. Danach wird zurück zur Entwurfsphase gewechselt und festgelegt, wie die Problemlösung verbessert werden kann. Dieses Vorgehen wiederholt sich so lange, bis das komplette Problem gelöst ist.
  • Prinzip der Aufteilung in Teilprobleme
    • Implementieren der Teilprobleme - Die Teilprobleme werden einzeln gelöst. Hier bietet es sich an, für jedes Teilproblem eine eigene Methode zu entwickeln, die das Teilproblem löst.

Die Ergebnisse dieser Phase werden in der Regel nicht im Anforderungsheft, sondern direkt im Quellcode mit Hilfe von Kommentaren dokumentiert.

Für das Beispiel könnten die einzelnen Lösungen so aussehen:

  • Prinzip der schrittweisen Verfeinerung
1. Schritt
void main() {
  vor();
  vor();
  vor();
}
2. Schritt:
void main() {
  vor();
  vor();
  vor();
 
  linksUm();
  linksUm();
  linksUm();
}
3. Schritt:
void main() {
  vor();
  vor();
  vor();
 
  linksUm();
  linksUm();
  linksUm();
 
  vor();
}
4. Schritt:
void main() {
  vor();
  vor();
  vor();
 
  linksUm();
  linksUm();
  linksUm();
 
  vor();
 
  gib();
  gib();
  gib();
  gib();
  gib();
}
  • Prinzip der Aufteilung in Teilprobleme
Bis zur Wand laufen:
void vorBisWand() {
  while (vornFrei()) {
    vor();
  }
}
Rechts rum drehen:
void rechtsUm() {
  linksUm();
  linksUm();
  linksUm();
}
Alle Körner ablegen:
void gibAlle() {
  while (!maulLeer()) {
    gib();
  }
}
Gesamtes Problem:
void main() {
  vorBisWand();
 
  rechtsUm();
 
  vorBisWand();
 
  gibAlle();
}

Testen

Die Phase des Testens ist sehr wichtig, z.B. um zu überprüfen, ob das Problem tatsächlich gelöst wurde.

  • Wird die Zielsituation erreicht?
  • Werden die „Regeln“ befolgt?
  • Funktioniert das Programm auch in ähnlichen Situationen?

Hier kann es passieren, dass man feststellt, dass es noch Probleme gibt. In diesem Fall muss man zurück in die Entwurfs- oder Implementierungsphase, um sicher zu stellen, dass alle möglichen Situationen vom Programm sicher behandelt werden. Dann beginnt der Kreislauf von neuem.

Im Beispiel könnte man beim Testen bemerken, dass bei der Lösung mit dem Prinzip der schrittweisen Verfeinerung nur ein bestimmter Anwendungsfall abgedeckt wird, nämlich wenn der Weg genau vier Kacheln lang ist und der Hamster genau fünf Körner im Maul hat. Hier sollte man noch nachbessern, indem den Programmcode so anpasst, dass man Schleifen verwendet. Die Lösung mit dem Prinzip der Aufteilung in Teilprobleme passt hier schon besser.

Dokumentation

Die Phase der Dokumentation läuft parallel zu den anderen Phasen. Um Nachvollziehbarkeit zu gewährleisten, müssen alle Arbeitsschritte dokumentiert werden. Außerdem muss der Programmcode mit Kommentaren oder selbsterklärenden Methoden lesbar gemacht werden!