molily: Programmstruktur bei aufeinander aufbauenden Abläufen

Beitrag lesen

Hallo,

ich stelle mir gerade eine grundsätzliche Frage. Man hat ziemlich oft solche Programmabläufe, insbesondere bei Datenbankabfragen (selbst bei OO-Interfaces wie mysqli):

$ergebnis1 = mach_was();  
if ($ergebnis1 === false) {  
   echo(\'Fehler!\');  
   return false;  
}  
$ergebnis2 = fahre_fort1($ergebnis1);  
if ($ergebnis === false) {  
   echo(\'Fehler!\');  
   return false;  
}  
$ergebnis3 = fahre_fort2($ergebnis2);

usw.

Sprich, Code baut aufeinander auf, aber an jeder Stelle kann irgendeine Funktion eine Ausnahme zurückgeben, die einer Sonderbehandlung bedarf. Dann soll der restliche Code nicht ausgeführt werden, sondern dieser Teil des Programmes vorzeitig abgebrochen werden - ich habe dies oben symbolisch mit return false angedeutet.

Ärger wird es dann bei verschachtelten Fallunterscheidungen, d.h. wenn man nicht einfach nur abbrechen will, sondern einen anderen Weg einschlagen will:

$ergebnis1 = mach_was();  
if ($ergebnis1 == \'a\') {  
   $ergebnis2 = mache_dies($ergebnis1);  
   if ($ergebnis2 == ...) {  
      ...  
   } else {  
      ...  
   }  
} elseif ($ergebnis1 == \'b\') {  
   $ergebnis2 = mache_das($ergebnis1);  
   if ($ergebnis2 == ...) {  
      ...  
   } else {  
      ...  
   }  
}

Solcher Code wird, selbst wenn man die Teile in mehrfach verwendbare Funktionen auslagert, schnell unübersichtlich und schwer zu übersehen.

In JavaScript würde ich so etwas weniger »imperativ« lösen, d.h. vielleicht mit Handlerfunktionen arbeiten, die sich dann in einer Kette aufrufen. Beim ersten Beispiel also etwa:

mach_was(fahre_fort1, fehler1);  
function mach_was (erfolg, fehler) {  
   var ergebnis = [mach_es];  
   ergebnis ? erfolg(ergebnis, fahre_fort2, fehler2) : fehler(ergebnis);  
}  
function fahre_fort1 (ergebnis_alt, erfolg, fehler) {  
   var ergebnis = [mach_es];  
   ergebnis ? erfolg(ergebnis) : fehler(ergebnis);  
}  
function fahre_fort2 () {...}  
function fehler1 () {...}  
function fehler2 () {...}

Der Sinn hier ist natürlich, dass man die Funktionen so allgemein hält, dass sie unterschiedliche Handlerfunktionen empfangen können, also in verschiedenen Abläufen/Ketten benutzt werden.

Ich finde das zumindest sinnvoller strukturiert als den obigen »Spaghetticode«. Aber wie löst man eine solche Handlerstruktur in PHP? Funktionen an andere übergeben und damit eine Kette anstoßen geht wohl nicht so einfach - auf Funktionsnamen als Strings will ich verzichten.

Bisher habe ich auf solche grundlegenden Fragen der Programmstrukturierung keine eindeutige Antwort gefunden. Bei OOP lagere ich die Funktionalität letztlich zwar in viele kleine Funktionen aus, die sich dann aufrufen, aber irgendwo habe ich zentral noch einen Ablauf, der aus einer Reihe von Fallunterscheidungen und Fehlerbehandlungen besteht. Wie lässt sich das sinnvoller lösen?

Mathias