Universität Ulm, Fakultät für Mathematik und Wirtschaftswissenschaften, SAI

WS 97/98 || Entwicklung objekt-orientierter Bibliotheken || Beispiele

Collections-10


TestLists Lists Collections PrintableObjects

Collections
Diese Version wurde unverändert von einem früheren Beispiel übernommen.

Lists
Diese Version wurde von einem früheren Beispiel übernommen und um die Unterstützung von PrintableObjects erweitert.

PrintableObjects
Dieses ist ein Beispiel für eine sekundäre Abstraktion. Sekundäre Abstraktionen basieren (im Gegensatz zu primären Abstraktionen) nicht auf einer statischen Erweiterung. Dies wäre in Oberon auch nicht ohne weiteres möglich, da mehrfache statische Erweiterungen (multiple inheritance) nicht unterstützt werden (im Gegensatz z.B. zu C++ oder Eiffel).

Der Nachteil einer sekundären Abstraktion besteht in der mangelnden Sicherheit des Aufrufers, ob die Abstraktion für ein bestimmtes Objekt unterstützt wird oder nicht. Im konkreten Beispiel wird eine fehlende Unterstützung durch gewisse voreingestellte Texte (sei es für den Stream oder global) ausgeglichen. Diese Voreinstellungen für nicht unterstützte Objekte können natürlich auch als Vorteil betrachtet werden, da andernfalls der Aufrufer jeweils entscheiden müßte, was zu tun ist, wenn das Objekt nicht unterstützt wird.

Bemerkenswert ist an diesem Beispiel, daß PrintableObjects zwei Sorten von Disziplinen verwendet: sowohl eine, die an Streams gehängt wird als auch eine für beliebige Objekte, die nachher auszugeben sind. Dabei kann es durchaus passieren, daß zwei Disziplinen (von beiden Typen je einmal) dieses Moduls an einem Objekt hängen. Das wäre der Fall, wenn Streams PrintableObjects unterstützen würde (z.B. durch Ausgeben des gesamten Streams).

TestLists
Um mit den anderen Modulen etwas besser spielen zu können, wurde eine etwas ausgefeilte Eingabe-Syntax zugelassen:

Expression = Integer |
	     List |
	     "$" Integer |
	     Op2 Expression Expression .
List =       "(" [ Expression { "," Expression } ] ")" .

Op2 =        "add" |    (* Collections.Add *)
	     "remove" . (* Collections.Remove *)

Jeder neu eingegebene Ausdruck wird einer Variablen zugewiesen, die anschließend mit $0, $1 usw. adressiert werden kann. Es gibt allerdings nicht beliebig viele Variablen, sondern nur einen Ringpuffer mit begrenzter Kapazität. So sieht z.B ein Dialog aus:

helios$ tlists
> (1, 2, 3)
$0 = (1, 2, 3)
> (4, 5, 6)
$1 = (4, 5, 6)
> ($0, $1)
$2 = ((1, 2, 3), (4, 5, 6))
> remove $2 $0
$3 = ((4, 5, 6))
> add $2 $0
$4 = ((4, 5, 6), (1, 2, 3))
> (3, 4
| , 5)
$5 = (3, 4, 5)
> helios$ 
Zu beachten ist, dass beim Entfernen (Operator remove) Zeigeridentität vorherrschen muß. Das läßt sich nur über Variablenverweise ($0, $1 usw.) erreichen.

Die Quellen stehen als Shell-Archiv zur Verfügung.
WS 97/98 || Entwicklung objekt-orientierter Bibliotheken || Beispiele

Andreas Borchert, 12. November 1997