Kontakt  Presse  reticon-Redakteure   Impressum   Datenschutz  
reticon Bildung und Neue Medien
reticon - Bildung und Neue Medien

Deus Ex Machina aus Sicht der Informatik

reticon-Report von Martin Ragg -- [04.04.2004]

Im Rahmen unserer Recherchen, wie gerade heute in den neuen Medien das Deus Ex Machina Prinzip verwendet wird, sind wir im Gespräch mit Roger Sennert auf eine neue, sehr interessante Parallele gestoßen.
Deus Ex Machina stammt verkürzt gesagt aus dem griechischen Theater. Hier bezeichnet man damit die Lösung einer verfahrenen Situation, im griechischen Theater tragen die Götter zur Fortführung der Handlung bei. Lesen Sie dazu auch unseren reticon-Report.

Reticon: Deus Ex Machina in der Informatik - d.h. also eine verworrene Situation und die Situation wird kreativ gelöst, damit es weiter geht. Gibt es das in der Programmierung?
Sennert: Ich finde gerade in der Informatik, insbesondere beim Programmieren, findet man sehr schöne Beispiele dafür. Es ist nahezu das täglich' Brot eines Entwicklers, mit solchen Dingen umzugehen. Die meisten Programme haben Situationen, welche für den Idealfall programmiert sind. Dies bedeutet, dass diese einwandfrei laufen, solange gewisse Randbedingung gegeben sind. Nun ist es aber leider so, dass es eine Vielzahl von Situationen gibt, die auf ein Programm zukommen können, wenn es erstmal den gut behüteten Stall des Entwicklers verlässt. In der großen, bösen Welt können tausende Dinge passieren, an die während der Entwicklung einfach nicht gedachten werden konnte.
Ein schönes Beispiel dafür ist, dass davon ausgegangen wird, dass man eine Datei immer öffnen kann. Oder dass man immer und zu jedem Zeitpunkt die Menge Speicher vom System bekommt, welche man braucht. Dies ist natürlich nicht das Fall! Man muss immer damit rechnen, dass diese Operationen misslingen können. In den genannten Beispielen ist es noch relativ überschaubar und man kann durch entsprechende Abfragen dafür sorgen, dass das Programm nicht in einen kritischen Status kommt - kurz gesagt abstürzt. Jedoch sind Entwickler ziemlich faule Menschen und solche Abfragen machen den Quellcode unübersichtlich.

Reticon:
Haben Sie vielleicht für unsere Lesen ein Beispiel, das man auch als "Nicht-Informatiker verstehen kann?

Sennert: Schauen wir uns einmal folgendes vereinfachtes "Programm" an:
Beispiel 1: Idealfall
1:    var datei    = oeffneDatei( "c:MeinGanzTollerText.doc );
2:    var groesse  = groesseDate( datei );
3:    var speicher = holeSpeicher( groesse );
4:    var erfolg   = leseDatei( datei, speicher );
5:    ausgabe( "Geschafft!" );

"oeffneDatei" öffnet eine Datei auf der Festplatte und gibt bei Erfolg einen sogenannten Handle zurück. Ein Handle ist eine Art Ausweis, den man beim System immer vorzeigen muss, wenn man etwas mit der Datei machen möchte - also z.B. lesen, schreiben, schließen.
"groesseDate" ermittelt die Dateigröße, welche die Datei hat. Somit wissen wir, wieviel Speicher wir reservieren muss, wenn man die Datei in den Speicher laden möchte.
"holeSpeicher" versucht Speicher zu reservieren. Auch hier erhalten wir vom System wieder einen Ausweis (Handle) zurück.
"leseDatei" liest nun die geöffnete Datei in den reservierten Speicher. Wenn es erfolgreich war, steht in der Variable Erfolg eine "Wahr", sonst ein "Falsch".

Dieses Beispiel stellt den absoluten Idealfall dar. So wird es auf jeden Fall immer auf dem System des Entwicklers funktionieren.
Was alles schief gehen könnte, fällt einem ziemlich leicht ein. Aber gehen wir es mal Schritt für Schritt durch.
Die Datei könnte zum Beispiel nicht mehr existieren und umbenannt worden sein. Oder sie liegt auf einem anderen Laufwerk. Oder sie wird gerade von einem anderen Programm verwendet. Oder, oder, oder ...
Es gibt viele Gründe, warum uns das System keinen gültigen Handle zurück geben kann. Wenn dies aber im oben gezeigten Beispiel passieren würde, gäbe es ziemliche Probleme. In Zeile 2 versuchen wir die Größe zu ermitteln. Mit einem ungültigen Handle würde das Programm eine nicht erlaubte Operation ausführen und somit abstürzen. Ebenso kann das System nicht mehr genügend Speicher haben und uns in Zeile 3 einen ungültigen Handle geben. Das Result wäre, dass es in Zeile 4 abstürzen würde.

Nun weiß man als Entwickler, dass solche Dinge schief gehen können und versucht sie abzufangen. Man prüft nach jeder Operation, ob sie erfolgreich war.

Beispiel 2: Normal mit Abfragen
  1:    var datei    = oeffneDatei( "c:MeinGanzTollerText.doc );
 2:    Wenn istGueltig( datei )
 3:    BEGIN
 4:       var groesse  = groesseDate( datei );
 5:       Wenn isGueltig( groesse )
 6:       BEGIN
 7:          var speicher = holeSpeicher( groesse );
 8:          Wenn isGueltig( speicher )
 9:          BEGIN
10:             var erfolg = leseDatei( datei, speicher );
11:             Wenn isWahr( erfolg )
12:              BEGIN
13:                 aushabe( "Geschafft..." );
14:              END
15:           END
16:        END
17:     END
18:     Sonst
19:     BEGIN
20:        ausgabe( "Konnte Datei nicht öffnen" );
21:     END

Puh! Das sieht schon nicht mehr so gut aus! Aber für die meisten Fällen sind wir jetzt auf der sicheren Seite. Noch kurz ein Wort zu dem BEGIN und END. Damit kennzeichnet man einen Block von Operationen. Wenn also in Zeile 2 das Handle nicht gültig ist, wird der Block darunter nicht abgearbeitet, sondern ein evtl. vorhandener "Sonst" Block. Ich habe hier nur einen "Sonst" Block gemacht, um die Funktionsweise zu demonstieren. Normal würde er hinter JEDEM "Wenn" ein Block kommen, um entsprechen reagieren zu können. Zum Beispiel müsste Speicher wieder freigeben werden, wenn das Einlesen das Datei erfolglos war. Aber ich denke man kann sich auch so ganz gut vorstellen, wie es aussehen würde. Und genau dort liegt das eigentliche Problem. Man verliert den Überblick -
oder anders ausgedrückt : Man sieht vor lauter Wald die Bäume nicht mehr. Und dies ist nur ein ganz kleines Beispiel, wie es zu Hauf in Programmen vorkommt. Normal sind die Operationen viel komplexer und länger. Man kann die Programmierer also verstehen, warum sie sich die Arbeit nicht machen und jeden "Mist" abfragen. Zudem hat man selbst mit diesen Möglichkeiten immer noch nicht alles abgefangen, was passieren könnte! Aber genau hier das die objektorientierte Programmierung Abhilfe geschaffen.

Reticon: Das was Sie gerade beschrieben haben, ist also gewissermaßen die verworrene Situation. Sie als Programmierer können sich nicht auf alle Fehlersituationen des Anwenderpcs vorbereiten. Und objektorientierte Programmierung ist jetzt Ihr Deus Ex Machina?

Sennert: Objektorientierte Programmierung (OOP) ist ein ziemlich komplex Thema. Aber wir brauchen daraus an dieser Stelle nur eine spezielles Konzept - die Exceptions. Mit Exceptions kann man grob gesagt verfahrene Situation wieder retten, ohne dabei den Überblick über den Quelltext zu verlieren. Es gibt einen sogenannten "TRY" Block, in dem erstmal versucht wird etwas zu machen. Sollte es in diesem Bereich zu irgendeinem Fehler kommen, dann wird vom System eine Exception geworfen. Diese kann, muss aber nicht, vom Programm mit einem "CATCH" Block abgefangen werden. Und das Besondere ist, dass dies jeden möglichen Fehler abfängt! Es gibt Fehler, auf die man eingestellt ist. Also zum Beispiel, dass eine Datei nicht vorhanden ist. Aber es gibt auch Situationen, die absolut unvorhersehbar sind.
Schauen wir uns nochmal das Programmbeispiel 1 an. Nach der Zeile 2 schreibt ein anderes Programm die Datei. Diese ist nun viel größer als vorher. Wir haben aber nur Speicherplatz für die alte Größe reserviert. Das System wird dies beim Einlesen bemerken und eine Systemexception auswerfen. Diese kann mit den normalen Mitteln nicht abgefangen werden. Das Programm wird abstürzen!
Mit einem "CATCH (ALL)" Block wird auch ein solcher Fehler abgefangen.
Generell sind mehrere "CATCH" Blöche möglich. Sie werden in der Reihenfolge ihres Auftretens abgearbeitet - sofern die Fehlerklasse stimmt. Dies bedeutet also: man kann zuerst die spezielle Exception abarbeiten und wenn nichts bis dahin gepasst hat, kann man eine "CATCH (ALL)" Block machen. Auf so viel Worte soll nochmal ein Beispiel für sich sprechen:

Beispiel 3: OOP
1:    Try
2:    BEGIN
3:       var datei    = oeffneDatei( "c:MeinGanzTollerText.doc );
4:       var groesse  = groesseDate( datei );
5:       var speicher = holeSpeicher( groesse );
6:       var erfolg   = leseDatei( datei, speicher );
7:       ausgabe( "Geschafft!" );
8:    END
9:    CATCH (ALL)
10:    BEGIN
11:        ausgabe( "Ging leider nicht!" );
12:    END

Wie man sieht ist es wieder schön übersichtlich geworden. Und egal, welcher Fehler passieren sollte, er wird nun abgefangen.
Es ist also im Prinzip so, also ob man ein Kind an die Leine nimmt und sagt "Lauf los!". Es kann machen, was immer es möchte. Wenn es jedoch in eine verfahrene Situation kommt zieht man einfach an der Leine und holt es zurück auf den sicheren Boden.
Wenn man diese Konzept überall im Programm einsetzt kann ein Programm nicht mehr abstürzen!

Reticon: Und welchen Gott lassen Sie als Programmierer hereinschweben?

Sennert: Man könnte im Prinzipt sagen, dass die Exceptions der Gott ist, welcher herreinschwebt und alles rettet, damit es weitergeht.

Reticon: Also könnte man gewagt behaupten, dass DEM durchaus ein Prinzip in der modernen Informatik ist?

Sennert: Ich würde dies auf jeden Fall so sagen!

Reticon: Vielen Dank für das Gespräch und die Einführung in objektorientierte Programmierung.

Weiterlesen

  •    1

Informationen zum Artikel

Aus den Terminen

RSS & Social Media

rss-Bild
rss-Bild
rss-Bild
rss-Bild

myreticon

E-Mail
Passwort Login

Infos & Hilfe | Registrieren

Kostenlose Newsletter

Wöchentliches Newsletter
Tägliche Medientipps

E-Mail:  

reticon-Quiz

Wofür steht eigentlich HTML
Ihre Antwort:
 

» Alle reticon Quiz-Fragen

Sprüche & Zitate

Non omnia possumus omnes.
Wir alle können nicht alles.

Vergil