Home > Informatik > Formale Sprachen > Folge 21: Eine Stackmaschine

21.2 Entwurfsdiagramm

21.1 - 21.2 - 21.3 - 21.4

Der Begriff "Entwurfsdiagramm" ist an sich etwas problematisch, denn offiziell gibt es keine Entwurfsdiagramme, sondern nur Klassendiagramme. Allerdings ist dieser Begriff sehr schwammig definiert, so dass man fast alle Zeichnungen, die Klassen in rechteckigen Kästen darstellen und durch Pfeile verbinden, als "Klassendiagramm" bezeichnen kann. Die NRW-Didaktiker verstehen unter einem Entwurfsdiagramm ein Klassendiagramm, das sehr einfach gehalten ist und keinerlei Hinweise auf eine mögliche Implentierung enthält, so dass es völlig egal ist, in welcher Programmiersprache man das Projekt verwirklicht.

Das ist der Vorteil eines Entwurfsdiagramms: Man kann es schon entwickeln, bevor man sich überhaupt für eine Programmiersprache entschieden hat, mit der man das Projekt verwirklichen möchte. Negativ könnte es man natürlich auch so formulieren: Ein Entwurfsdiagramm kann jeder erstellen, der keine Ahnung vom "richtigen" Programmieren hat. Aber wir wollen ja nicht negativ sein! Und im Informatikunterricht geht es ja auch nicht in erster Linie um "richtiges Programmieren", sondern um das Verständnis von Algorithmen und Informatik-Konzepten sowie um allgemeine Themen wie Datensicherheit, Industrie 4.0, autonomes Fahren etc.

Erster Entwurf

Hier nun ein erster Entwurf eines solchen Entwurfsdiagramms:

Entwurf eines Entwurfsdiagramms (pun intended!)

Ein Stackinterpreter (hier einfach Interpreter genannt) HAT drei wichtige Komponenten, eine Variablenliste, einen Codebuffer und eine Stackmaschine. Diese Komponenten werden durch Objekte der Klassen Varlist, Codebuffer und Stackmachine repräsentiert. Die Stackmachine ist wiederum ein Stack, der rechnen kann. Hier sehen wir eine IST-Beziehung im Diagramm.

Eine Stackmaschine ist ein Stack, der rechnen kann. Stehen beispielsweise die Zahlen 3 und 4 ganz oben im Stack, führt der Stackmaschinen-Befehl "ADD" dazu, dass die beiden Zahlen gepoppt werden und dafür das Ergebnis der Addition, also die Zahl 7, gepusht wird. Entsprechend arbeiten die Operationen SUB, MUL und DIV der Stackmaschine. Wie man in dem Diagramm sieht, ist die Klasse Stackmachine eine Tochterklasse der Klasse Stack, die wir bereits in der Q1 behandelt hatten.

Ein Stackinterpreter ist aber mehr als eine einfache Stackmaschine. In einem Objekt der Klasse Codebuffer werden die Steuerbefehle der Stackmaschine gespeichert. Der Interpreter geht dann diese Befehle durch und interpretiert sie, führt sie also aus.

Für einfache Rechnungen braucht man keine Variablen. Soll aber beispielsweise der Umfang eines Kreises berechnet werden, so muss der Radius des Kreises in einer Variablen gespeichert werden. Soll mit dem Umfang weitergerechnet werden, muss auch dieser in einer Variablen gespeichert werden. Um die Verwaltung dieser Variablen kümmert sich ein Objekt der Klasse Varlist.

Zweiter Entwurf

In dem ersten groben Entwurf standen eigentlich nur die Namen der beteiligten Klassen; Attribute und Methoden wurden noch nicht aufgelistet. Das wollen wir mit dem zweiten Entwurf versuchen.

Das konkretere Entwurfsdiagramm

Die Klasse Stack hat keine nach außen sichtbare Attribute, nur der Konstruktor und die vier Methoden sind bekannt. Die Klasse Stackmachine hat ebenfalls keine sichtbaren (oder relevanten) Attribute, ergänzt die Klasse Stack aber um vier Rechenmethoden.

Die Klasse Codebuffer hat ein Attribut, das die einzelnen Zeilen eines Quelltextes speichern kann. Ob das nun mithilfe eines Arrays, einer ArrayList, eines Stacks oder mit einer anderen Datensammlung vom Typ Text gemacht wird, bleibt im Entwurfsdiagramm offen. Der Java-Datentyp String taucht übrigens in diesem Entwurfsdiagramm nicht auf - das ist typisch für ein Entwurfsdiagramm, es soll ja unabhängig von einer konkreten Programmiersprache sein. In Java würde man dann den Typ Text durch den Datentyp String implementieren.

Dem Konstruktor muss der Name einer Textdatei mitgeteilt werden. Mit der Operation read wird die Textdatei in den Buffer gelesen, mit der sondierenden Methode getNextCmd wird der nächste Befehl zurückgegeben, der gerade anliegt, und mit getNextArg wird das Argument dieses Befehls zurückgeliefert.

Angenommen, der nächste Befehl, der ausgeführt werden soll, lautet PUSH 17, dann würde getNextCmd den Text "PUSH" liefern und getNextArg die Zahl 17.

Der Interpreter geht alle Befehle des Codebuffers durch. Dabei kann er vorher immer überprüfen, ob er das Ende des Buffers bzw. das Ende der Textdatei erreicht hat. Das wird durch die Methode EOF des Codebuffers möglich. "EOF" ist die Abkürzung für "end of file" und hat den Wert TRUE, sobald das Ende der Datei / des Buffers erreicht ist.

Die Variablenliste Varlist enthält als Attribut eine Sammlung von Objekten der Klasse Variable. Das kann zum Beispiel ein Objektarray oder eine ArrayList sein. Mit dem Befehl assign wird einer bereits vorhandenen Variable ein neuer Wert zugeweisen. Sollte die Variable noch nicht in der Liste vorhanden sein, wird die private Methode insert aufgerufen und eine entsprechende Variable erzeugt. Mit der Methode getValue wird der Zahlenwert einer bestimmten Variablen zurückgegeben.

Eine Variable selbst ist ein Objekt der Klasse Variable. Eine Variable besteht immer aus einem Namen vom Typ Text und einem Wert vom Typ Zahl. Mit setValue wird der Wert gesetzt oder verändert, mit getValue wird der Wert ermittelt, und mit getName wird der Name der Variable ermittelt.

Damit ist das Projektvorhaben schon sehr genau beschrieben. Auf die einzelnen Klassen wird auf den nächsten Seiten noch genauer eingegangen - lassen Sie sich bitte nicht von den vielen Klassennamen und Methodennamen auf dieser Seite abschrecken, das ganze Projekt ist gar nicht so schwer zu modellieren und zu implementieren. Bisher hat es jeder meiner Informatikkurse geschafft!

Weiter mit 21.3 - Stackmaschine...