
\section{Eiffel}\label{Effl}
Die in der Programmiersprache Eiffel \cite{Mey92,Swi92} entwickelten
Klassenbibliotheken zeichnen sich durch eine gro"se Anzahl angebotener Klassen
und starke Strukturierung aus. Die Entw"urfe der unterschiedlichen Anbieter
orientieren sich alle stark an dem urspr"unglichen Entwurf, wie er in
\cite{Mey94b} beschrieben ist. Abschnitt \ref{EiffelSprache} beschreibt
kurz die wesentlichen Eigenschaften der Sprache, der darauf folgende
Abschnitt \ref{EiffelBibliothek} die Struktur der Beh"alterklassen-Hierarchie
der Klassenbibliothek von Eiffel. Abschnitt \ref{EiffelFazit} fa"st die
Ergebnisse zusammen. 

\subsection{Sprache}\label{EiffelSprache}
Der Entwurf der Programmiersprache Eiffel zielt direkt auf die sprachliche
Unterst"utzung qualit"atssichernder objektorientierter Bibliotheksentwicklung.
Der Zielsetzung der Wiederverwendbarkeit und Erweiterbarkeit von
Softwarebibliotheken entsprechend, bietet Eiffel Mehrfachvererbung,
wiederholte Vererbung und eine Form des gebundenen parametrischen
Polymorphismus f"ur Klassendefinitionen. Die Entwicklung zuverl"assiger Systeme
wird durch strenge Typisierung und vielf"altige M"oglichkeiten zur Formulierung
von Invarianten sowie Vor- und Nachbedingungen unterst"utzt ({\em design by
contract} \cite[S.23]{Mey94a}). F"ur letztere wird auch der Zugriff auf den
Zustand vor Ausf"uhrung einer Methode angeboten.
 
Zur weiteren Flexibilisierung des Vererbungsmechanismus und zur Aufl"osung
von Namenskonflikten k"onnen Methoden umbenannt ({\sf rename}) werden.
Ebenfalls der Flexibilisierung dient die M"oglichkeit, bei der Redefinition
({\sf redefine}) von Methoden auch eine Ver"anderung der Signaturen
vorzunehmen. Zus"atzlich erm"oglicht Eiffel, Methoden auch vollst"andig aus
der Schnittstelle einer Klasse zu entfernen ({\sf undefine}). Der Einsatz der
Vererbung zur Abstraktion und Klassifizierung wird durch die M"oglichkeit
unterst"utzt, abstrakte Klassen und Methoden zu definieren.

W"ahrend C++ mit Hilfe der Schl"usselworte {\sf public, protected} und {\sf
private} nur die Unterscheidung zulie"s, eine Methode f"ur alle Benutzer
anzubieten oder ihre Zugreifbarkeit auf die Klasse oder die Klasse und ihre
Erben zu beschr"anken, bietet Eiffel eine flexiblere Zugriffskontrolle an. 
Die Kapselung von Methoden gegen"uber Klienten einer Klasse kann f"ur jede
Methode explizit durch Angabe der Klassen, denen der Zugriff erlaubt ist,
festgelegt werden. Dabei ist es sowohl m"oglich, allen anderen Klassen den
Zugriff zu erlauben (entspricht {\sf public} in C++), als auch den Zugriff
aller anderen Klassen zu unterbinden (entspricht {\sf private} in C++).
Werden keine Angaben gemacht, so sind Methoden f"ur alle Klienten
zugreifbar. Der so festgelegte Exportstatus einer Methode wird prinzipiell von
Subklassen "ubernommen. Er kann aber von diesen beliebig ver"andert werden.

Das Typsystem basiert auf der Klassendefinition. Jeder Typ wird direkt oder 
indirekt von einer Klasse abgeleitet. Auf den Typen ist eine der Subtyprelation
"ahnliche Konformit"atsrelation definiert, welche die Konsistenzbedingung f"ur
z.B. Zuweisungen, Parameter"ubergaben und Redefinitionen von Methodensignaturen
darstellt \cite[S.117ff]{Mey92}. Diese Relation entspricht f"ur nicht
parametrisierte Typen der Vererbungsrelation. F"ur von generischen Klassen
beschriebene parametrisierte Typen wird die Konformit"atsbeziehung zwischen
den durch Instantiierung abgeleiteten Typen betrachtet. Die Konformit"at dieser
Typen ist daher zus"atzlich zur Vererbungsbeziehung noch abh"angig von den f"ur
die Instanttierung verwendeten Typen.

Bei der Redefinition von  Methoden lassen die Regeln zur Einhaltung der
Konformit"atsbeziehung die  kovariante Spezialisierung von Parametertypen zu.
Aufgrund dessen und wegen der M"oglichkeit zur Ver"anderung des Exportstatus
einer Methode ben"otigt die abschlie"sende Typ"uberpr"ufung eine potentiell
systemweite Analyse zum Bindungszeitpunkt \cite[S.364]{Mey92}.

Funktionen haben in Eiffel keinen '{\em first class object}'-Status, d.h. sie
k"onnen nicht als Aktualparameter oder R"uckgabewert auftreten. Ein
Metaklassenkonzept existiert ebenfalls nicht. Objekterzeugungsmethoden sind
Bestandteil der Klassendefinition und beziehen sich auf eine konkret
deklarierte Variable, welche das erzeugte Objekt aufnimmt.


\subsection{Die Eiffel-Bibliothek}\label{EiffelBibliothek}
Einen "Uberblick "uber die Bibliothek bietet Abbildung \ref{EiffelBib}.  
Die Abbildung zeigt die Massen\-da\-ten\-typen\--Hierarchie der
Eiffel-Klassenbibliothek. 
Abstrakte Klassen sind in der Abbildung durch einen Stern neben dem Namen der
Klasse gekennzeichnet. An einigen Stellen sind, um die "Ubersichtlichkeit zu
erh"ohen, nicht alle Erbbeziehungen eingezeichnet. In solchen F"allen wird die
fehlende Erbbeziehung nur durch einen kurzen Strich angedeutet.

\renewcommand{\epsfsize}[2]{1.0#1}
\begin{figure}[hbt]
\begin{center} 
\leavevmode
\epsfxsize=14cm
\epsffile{../Bilder/thorsten/Postscript/Eiffel-Ueberblick.ps}
\end{center}
\caption{Ausschnitt der Eiffel-Klassenbibliothek} \label{EiffelBib}
\end{figure}

In der Abbildung zeigt sich eine von der Organisation der bisher betrachteten
Bibliotheken abweichende Struktur der Eiffel-Bibliothek. W"ahrend die Ableitung
der Beh"alter von {\sf Collection} den anderen Bibliotheken nachempfunden
ist, zeigt sich mit den in anderen Bibliotheken nicht vorhandenen Klassen {\sf
Box} und {\sf Traversable} ein neues Vorgehen bei der Organisation
objektorientierter Bibliotheken.
Die Eiffel-Bibliothek teilt die angebotene Funktionalit"at in 3 Bereiche ein:
\begin{itemize}
\item Speicherung: Die unter {\sf Box} beginnende Hierarchie enth"alt
Funktionalit"at, die im Zusammenhang mit der Speicherung der Elemente der
Beh"alter steht. Hier finden sich beispielsweise Methoden zur Feststellung der
Gr"o"se der Beh"alter, ihrer Kapazit"at und f"ur die Anpassung der Kapazit"at
verwendete Variablen. 
\item Zugriff: Unter {\sf Collection} ist die auf den Zugriff bezogene
Funktionalit"at der Bibliothek angeordnet. In diesem Teil der Hierarchie
befinden sich unter anderem Methoden zum Einf"ugen und L"oschen von Elementen
sowie zum Suchen von Elementen in den jeweiligen Beh"altern. 
\item Traversierung: Protokoll zum Traversieren der Beh"alter bietet die
Hierarchie unter der Klasse {\sf Traversable}. Bei der Traversierung gibt es
ein aktuelles Element des Beh"alters, auf das mit {\sf item} zugegriffen werden
kann.
\end{itemize}
Der gr"o"ste Teil der Klassen der Bibliothek ist abstrakt. Dies unterst"utzt
die These, in objektorientierten Bibliotheken k"onne ein Gro"steil der
Funktionalit"at entkoppelt von der Repr"asentation der Daten in den abstrakten
Klassen der Vererbungshierarchie realisiert werden. Klassen, die
instantiierbar sein sollen, kombinieren die Funktionalit"at der 3 Pfade und
implementieren die noch abstrakten Methoden in Abh"angigkeit von der dann
jeweils gew"ahlten konkreten Repr"asentationsform der Daten. Die
Eiffel-Bibliothek ist damit ein Beispiel f"ur die gegen"uber modulorientierten
Bibliotheken "uberlegene Kombinierbarkeit objektorientierter Bibliotheken.
Abbildung \ref{EiffelMethodenV} zeigt die Verteilung der Methoden auf die
Klassen der Eiffel-Bibliothek.

\renewcommand{\epsfsize}[2]{0.95#1}
\begin{figure}[hbt]
\begin{center} 
\leavevmode
\epsfxsize=14cm
\epsffile{../Bilder/thorsten/Postscript/Eiffel-MethodenVerteilung.ps}
\end{center}
\caption{Verteilung der Methoden der Eiffel-Klassenbibliothek} \label{EiffelMethodenV}
\end{figure}

Um die Qualit"at der Eiffel-Bibliothek zu beurteilen, mu"s auch diese
Bibliothek daraufhin untersucht werden, ob und in welchem Ma"s die abstrakten
Klassen der Bibliothek eine gemeinsame und einfache Sicht auf das Protokoll der
komplizierteren Klassen bieten. Die thematische Aufteilung des Protokolls
in 3 Bereiche k"onnte das Erreichen dieses Ziels erleichtern, da die Klassen
der Eiffel-Bibliothek nicht die Spezialisierung ganzer Beh"alter, sondern
lediglich die Spezialisierung von Protokollausschnitten realisieren m"ussen.
Die Gefahr von Konflikten zwischen geerbten und geplanten 
Eigenschaften einer Subklasse ist durch diese Konstellation geringer als in den
anderen Bibliotheken. 

Eine Durchbrechung der einheitlichen Sicht der abstrakten Klassen auf die
komplexen instantiierbaren Klassen f"ur die Benutzer ist in Eiffel durch die
Anwendung der in Abschnitt \ref{EiffelSprache} beschriebenen M"oglichkeiten zur
Umbenennung von Methoden und zur Ver"anderung der Sichtbarkeit der Methoden
m"oglich.

Eine Analyse des Quelltextes der Bibliothek zeigt, da"s auch in Eiffel ein
Vielzahl von Methoden umbenannt ({\sf rename}) wird. Umbenennungen erfolgen in
den Klassen {\sf Linear, Indexable, Hash\_table} und {\sf Table} sowie
zus"atzlich noch in den nicht in der Abbildung enthaltenen Klassen {\sf
Arrayed\_circular, Arrayed\_list, Chain, Dynamic\_list,
Linked\_circular, Two\_way\_circular, 
Two\_way\_list, Fixed\_list, Arrayed\_tree, Binary\_search\_tree,
Linked\_tree, Two\_way\_tree, Comparable\_set, Arrayed\_queue,
Arrayed\_stack, Linked\_queue, Linked\_stack, Sorted\_priority\_queue,
Heap, Fixed\_queue, Fixed\_stack, Array2, Sorted\_struct,
Compact\_cursor\_tree, Cursor\_tree, C\_tree\_iter} und {\sf Twc\_iter}.

Auch von der M"oglichkeit, geerbte Methoden zu L"oschen ({\sf undefine}) wird
in Eiffel ebenfalls in vielen Klassen Gebrauch gemacht. Im einzelnen sind dies
die Klassen {\sf Seq\_string, Active, Arrayed\_circular, Arrayed\_list, Chain,
Circular, Dynamic\_chain, Dynamic\_circular, Dynamic\_list, Linked\_circular,
List, Sorted\_list, Sorted\_two\_way\_list, Two\_way\_circular, Fixed\_list, 
Part\_sorted\_two\_way\_list, Arrayed\_tree, Linked\_tree, Two\_way\_tree,
Comparable\_set, Linked\_set, Sorted\_set, Part\_sorted\_set, Arrayed\_queue,
Arrayed\_stack, Linked\_queue, Linked\_stack, Sorted\_priority\_queue,
Fixed\_queue, Fixed\_stack, Array2} und {\sf Sorted\_struct}.

Abbildung \ref{EiffelShouldNot} zeigt das Entfernen einer Methode aus der
Schnittstelle am Beispiel der Klasse {\sf Table}. In {\sf Collection} (hier nur
verk"urzt dargestellt) wird die Methode {\sf put} mit einem Parameter
eingef"uhrt: 
\begin{xple}
deferred class COLLECTION [G] inherit
   CONTAINER [G]
feature $--$ Element change
   put, extend (v: G) is  $--$ Ensure that structure includes `v'.
      require extendible: extendible deferred
      ensure item\_inserted: has (v) end;
end $--$ class COLLECTION
\end{xple}
"Uber die Eigenschaften von {\sf Table} sagt die im Quelltext der Klasse
enthaltene Beschreibung jedoch, da"s der Zugriff auf die Elemente einer {\sf
Table} mit Hilfe eines Index erfolgt. Die Eigenschaft, Elementen einen Index
zuzuordnen, ist jedoch nicht konform mit der M"oglichkeit, ein Element ohne
Angabe eines solchen Index in die {\sf Table} einf"ugen zu k"onnen. Die Methode
{\sf put} wird daher in {\sf Table} (ebenfalls verk"urzt dargestellt) umbenannt
(in {\sf bag\_put}) und eine neue Methode zum Einf"ugen unter Verwendung des
alten Namens {\sf put} mit 2 Parametern eingef"uhrt. Das aus der Umbenennung
des geerbten {\sf put} entstandene {\sf bag\_put} wird so "uberschrieben, da"s
sein Aufruf keinerlei Aktion zur Folge hat. Gleichzeitig wird die
Zugriffskontrolle bez"uglich der Methode {\sf bag\_put} so ge"andert, da"s der
Aufruf der Methode f"ur Objekte anderer Klassen nicht mehr m"oglich ist:
\begin{xple}
deferred class TABLE [G, H] inherit 
   BAG [G] $--$ Containers whose items are accessible through keys
     rename put as bag\_put end;
feature $--$ Element change
   put (v: G; k: H) is $--$ Associate value `v' with key `k'.
     require valid\_key: valid\_key (k) deferred
     ensure insertion\_done: item (k) = v end;
feature {NONE} $--$ Inapplicable
   bag\_put (v: G) is do end
end $--$ class TABLE
\end{xple}

\renewcommand{\epsfsize}[2]{1.0#1}
\begin{figure}[hbt]
\begin{center} 
\leavevmode
\epsfxsize=12cm
\epsffile{../Bilder/thorsten/Postscript/Eiffel-ShouldNotImplementSmall.ps}
\end{center}
\caption{Beispiel f"ur das Entfernen von Methoden in der Eiffel-Bibliothek}
\label{EiffelShouldNot} 
\end{figure}

\section{Fazit}\label{EiffelFazit}
In Kapitel \ref{SoftBibs} wurde "Ubersichtlichkeit als wesentliches
Qualit"atsmerkmal f"ur Softwarebibliotheken neben den allgemeinen Merkmalen
wie Korrektheit herausgestellt. Der Vergleich der vorherrschenden
Grundstrukturen f"ur Softwarebibliotheken in Kapitel \ref{Grundstrukturen}
zeigt, da"s die Verwendung einer objektorientierten Bibliothek die Entwicklung
einer "ubersichtlichen Bibliothek beg"unstigt. Zus"atzlich bietet
Objektorientierung die M"oglichkeit der Kombination von Funktionalit"at durch
die Entkoppelung der Funktionalit"at von der Repr"asentation der Daten.

In diesem Kapitel wurden C++, Smalltalk und Eiffel daraufhin verglichen, welche
Eigenschaften der Sprachen Auswirkungen auf die Gestaltung der jeweiligen
Beh"alterbibliothek haben. Dabei ist festzustellen, da"s alle untersuchten
Sprachen "uber die M"oglichkeit partiellen Erbens verf"ugen. Bei allen
untersuchten Bibliotheken dieser Sprachen wurde von dieser M"oglichkeit
ausgiebig Gebrauch gemacht. Somit ist partielles Erben eine wesentliche
Spracheigenschaft in Bezug auf die Gestaltung von Bibliotheken.

Das mit partiellem Erben verbundene Entfernen von Methoden aus der
Schnittstelle erbender Klassen geschieht entweder mit Hilfe von
Schl"usselworten ({\sf rename} oder {\sf undefine} in Eiffel, {\sf private} in
C++) oder durch "Uberschreiben mit einer durch Konvention festgelegten Methode,
deren Aufruf eine Fehlermeldung erzeugt.
Durch diese Verfahren partiellen Erbens ergeben sich erhebliche
Unterschiede zwischen der Vererbungs- und der Schnittstellenhierarchie der
Bibliotheken. Die F"ahigkeit abstrakter Klassen, eine einfache und 
gemeinsame Sicht auf verschiedene komplexe Klassen anzubieten, wird in allen
untersuchten Bibliotheken zerst"ort, so da"s die Bibliotheken die in Kapitel
\ref{SoftBibs} genannten Qualit"atsanforderungen bez"uglich der
"Ubersichtlichkeit nicht erf"ullen.

Entgegen der in der Literatur vertretenen These, Vererbung sei nur ein
Produzentenmechanismus \cite{Mey90c} und die Durchbrechung des Prinzips der
Spezialisierung n"otig \cite{CN94}, verfolgt diese Arbeit das Ziel, Vererbung
zum Nutzen von Produzenten und Konsumenten der Bibliothek einzusetzen. Die im
Rahmen der Diplomarbeit verwendete objektorientierte Programmiersprache TooL
bietet daher konsequenterweise auch keinerlei Unterst"utzung partiellen Erbens
an. In der TooL-Beh"alterklassenbibliothek sind daher Vererbungs- und 
Schnittstellenhierarchie identisch, so da"s jede Klasse eine einfache und
gemeinsame Sicht auf die Schnittstellen ihrer Subklassen anbietet.

