Objektorientierte Ressourcen-Teilung: Exemplarbildung und Vererbung

Fionn Behrens
Lars Eilebrecht
Frank Thilo


Inhaltsverzeichnis


1. Einleitung

Dieser Text behandelt eines der wichtigsten Probleme des Software-Engineerings und zwar die Wiederverwendung und die verschiedenen Ansätze zur Erreichung von Wiederverwendbarkeit. Das Problem ist allseits bekannt - auch heute noch wird das Rad viel zu oft neu erfunden, weil der Fortschritt in der Softwareentwicklung erst am Beginn einer allgemeinen Standardisierung und höheren Abstraktion in der Planung steht.

Bevor jedoch auf Vererbungstechniken, das Hauptwerkzeug der Wiederverwendung, eingegangen wird, wird zuerst einmal aufgezeigt, daß es sehr wohl auch schon lange vor den objektorientierten Sprachen Ansätze zu Wiederverwendung gab, die allerdings naturgemäß mit dem objektorientierten Ansatz verwandt sind, bzw. auch heute noch häufig in OO-Sprachen (objektorientierten Sprachen) wiederzufinden sind.

Das der Wiederverwendung zugrundeliegende Prinzip ist die Verallgemeinerung. Damit ist gemeint, daß Programmteile so implementiert werden, daß ihre Struktur und ihre Schnittstellen - also ihre Ein- und Ausgabeparameter - einem gewissen Standard genügen, der eine spätere Wiederverwendung möglich macht. Um dieses Ziel zu erreichen, wurden auch schon vor der OO verschiedene Ansätze gemacht.




2. Wiederverwendung ohne objektorientierte Programmiermethoden

2.1. Libraries / Funktionsbibliotheken

Libraries sind i.A. vorkompilierte Sammlungen von Routinen zur Behandlung spezieller, häufig algorithmischer Probleme. Dieser schon fast klassisch zu nennende Ansatz zur Wiederverwendung ist limitiert durch die Tatsache, daß das Programmieren mit Libraries nur dann übersichtlich bleibt, wenn der Satz der verwendeten Parameter klein und die durch die verschiedenen Routinen behandelten Probleme einfach und deutlich unterscheidbar sind. Auch die Verwendung komplexer Datenstrukturen würde zu Problemen führen, da diese zwischen den Routinen der Library und des Programms hin- und hergereicht werden müßten, wodurch die konzeptionelle Autonomie der Bibliothek verloren ginge.

Programme greifen i.A. zur Laufzeit auf die Libraries zu (Ausnahmen werden hier konzeptionell dem Bereich der Module zugeordnet, s.u.). Darin ist eine weitere Beschränkung der Libraries begründet: sie lassen sich nicht oder nur sehr schlecht warten oder an spezielle Bedürfnisse anpassen, was ihre Wiederverwendbarkeit am meisten begrenzt. Trotz dieser Einschränkungen werden Libraries heutzutage in wissenschaftlichen Applikationen und auch in vielen modernen Betriebssystemen, z.B. UNIX, erfolgreich eingesetzt.


2.2. Module/Packages

Ein in verschiedenen Computersprachen angewandtes Mittel, um Quelltext allgemein wiederverwendbarer zu gestalten, sind die sogenannten Module oder Packages. Hierbei wird ein Problem in sinngemäß getrennte Funktionsblöcke unterteilt, die sogenannten Module. Diese Module haben definierte Schnittstellen in Form von festen Parametern für Ein- und Rückgabewerte wie die Libraries. Zudem besteht hier bereits die Möglichkeit zum Information hiding also der Kapselung der Routinen und ihrer Variablen nach außen. Was in den Modulen wirklich stattfindet, braucht der Programmierer nicht zu wissen, er kennt lediglich die Wirkungsweise. In Modulen lassen sich mehrere Routinen zur Behandlung eines Problems zusammenfassen, z.B. Routinen zum Einfügen, Löschen und Sortieren einer Liste. Dieses Prinzip ist schon ein großer Schritt hin zur Datenabstraktion, bietet aber keinen wirklich neuen Ansatz, und auch der Entwicklungsaufwand wird nicht merklich reduziert, denn das Modulsystem hat ebenfalls Grenzen und Beschränkungen hinsichtlich des Ziels der Wiederverwendbarkeit.

So zwingen Module beispielsweise dem Programmierer bereits zur Planungszeit die Verwendung der Datentypen auf, die sie verarbeiten. Der Hauptunterschied zwischen Libraries und Modulen besteht darin, daß die Funktionen von Modulen grundsätzlich vom Compiler ins Programm eingebunden werden. Dadurch, daß die Module also als Quelltext vorliegen, ist eine gegenüber den Libraries erhöhte Wartbarkeit und Wiederverwendbarkeit gewährleistet.


2.3. Overloading (Überladen)

Overloading ist eine Technik, die es dem Programmierer erlaubt, den gleichen Algorithmus mehrmals unter dem gleichen Namen für verschiedene Argumenttypen zu erzeugen. Also zum Beispiel Wurzelfunktionen für Argumente vom Typ Ganzzahl und Gleitkommazahl. Der Compiler entscheidet dann während des Kompiliervorgangs anhand des beim Aufruf verwendeten Typs, welche der Funktionen in jedem speziellen Fall zu verwenden ist. Der Programmierer kann also mit Hilfe des Overloadings Programmsegmente bereitstellen, bei deren Verwendung er sich später keine Gedanken mehr über den Argumenttyp machen muß. Nichtsdestotrotz erkennt man leicht, daß dieser Ansatz rein kosmetischer Art und lediglich für den Programmierer hilfreich ist.



2.4. Genericity

Ein nicht direkt übersetzbarer Begriff, der jedoch eng mit dem Prinzip der generischen Datentypen verwandt ist. Die Idee ist, ein generisches Funktionsmodul zur Lösung eines bestimmten Problems zu implementieren, welches erst beim Übersetzen vom Compiler mit den passenden Typzuweisungen versehen wird. Diese Methode ist natürlich nur auf relativ einfache Funktionen anwendbar, die sich mehr oder weniger nur in der Deklaration der verwendeten Variablen unterscheiden. Bei komplexeren Problemen, die für unterschiedliche Typen auch unterschiedliche Algorithmen erfordern, ist nur das Prinzip des Overloading anwendbar. Trotzdem ist dies eine hervorragende Alternative zur Schaffung von Gruppen von Modulen, die sich funktional nicht unterscheiden und nur im Typ der Variablen, die sie manipulieren, verschieden sind.



2.5. Verbleibende Probleme

Das Problem ist jetzt, das alle diese Variationen zu viele Faktoren beinhalten, die noch zu unflexibel sind. Am einfachsten ist dies bei den Libraries mit ihrem starren System aus streng typisierten und parametrisierten Funktionen erkennbar. Der generische Ansatz hingegen ist offen für Variationen, aber nur sehr beschränkt einsetzbar. Die völlig vorgefertigten Module sind wiederum direkt nutzbar, aber für Änderungen ungeeignet. Overloading kann als eher kosmetische Lösung auch nicht als der Schlüssel zur Lösung betrachtet werden.

Außerdem erlaubt keine dieser Techniken dem Client-Programm (d.h. dem Programm, welches die Module, Libraries usw. benutzt) mehrere Implementationen der Datenabstraktion zu verwenden, ohne zu wissen, welche in jedem der Fälle verwendet wird. Die Programmierer müssen immer noch in der Planungsphase vorentscheiden, mit welchen Typen sie arbeiten wollen. Das soll heißen: der Programmierer braucht sich zwar z.B. bei Modulen nicht damit zu beschäftigen, wie beispielsweise hashtables implementiert werden, muß aber durchaus noch selbst vorher die verwendeten Variablentypen festlegen, mit denen gearbeitet werden soll.

Wirklich völlige Unabhängigkeit von der Repräsentation durch Variablen haben wir erst, wenn ein Client-Programm eine Funktion beinhalten kann, in der steht: Search(x,t) und das bedeutet: Suche nach x im Table t und benutze dabei den am besten geeigneten Algorithmus, egal von welchem Typ x und t gerade sind.

Und dieser Grad an Flexibilität, der so essentiell wichtig beim Schreiben von wiederverwendbarer Software ist, kann nur durch objektorientiertes Design erreicht werden.


3. objektorientierte Ansätze zur Wiederverwendung

3.1. Objektorientiertes Design

Um die bei der klassischen Programmentwurfmethode in Bezug auf die Wiederverwendung verbleibenden Probleme zu lösen, wird bei der objektorientierten Programmentwicklung ein neuer Designansatz verfolgt.

Beim klassischen Design wird zur Lösung eines Problems erst einmal ein Algorithmus benötigt, der eine Problemlösung anhand einzelner diskreter Schritte, die nacheinander ausgeführt werden müssen, beschreibt. Diese abzuarbeitenden Aktionen werden dann in der Regel weiter in kleinere Einzelschritte zerlegt, bis diese primitive Rechenvorgänge darstellen, die nicht mehr weiter analysiert werden müssen. Das Problem wird also anhand der zur Lösung notwendigen Aktionen unterteilt.

Beim objektorientierten Design hingegen wird das Gesamtsystem in Kategorien von Objekten unterteilt, die direkt der Problemstellung entnommen werden, und nicht spezifisch für einen bestimmten Algorithmus zur Problemlösung sind.

Somit findet hier eine unmittelbare Modellierung des Problemraums statt, wohingegen beim klassischen Ansatz zuvor noch eine Abbildung vom Problem- zum Lösungsraum erfolgt. Dies hat zur Folge, daß die objektorientierte Lösung wesentlich flexibler auf Änderungen des Problems reagiert, da sich diese Änderungen direkt in den Objektkategorien widerspiegeln, d.h. kleine Änderungen des Problems führen auch zu kleinen Änderungen des Modells.

Für die klassische Lösung hingegen gilt dies aufgrund der zusätzlichen Abbildung vom Problem- zum Lösungsraum nicht. Selbst Detailänderungen des Problems können zu sehr großen Änderungen der Lösung führen. Der gefundene Algorithmus kann sich sogar als vollkommen ungeeignet für das neue Problem erweisen.

Weiterhin ist es im Hinblick auf die Wiederverwendung ebenfalls sinnvoller, sich darauf zu verlassen, daß in zukünftigen Projekten die Datenstrukturen wiederverwendet werden können, als darauf zu hoffen, daß spezifische Algorithmen noch einmal Verwendung finden werden (z.B. werden sich Textverarbeitungsprogramme immer mit Dokumenten, Absätzen und Schriftarten befassen, auch wenn die Fähigkeiten der Programme große Unterschiede aufweisen).

Dies gilt aber nur, wenn die Objektkategorien auf einem ausreichend hohen Abstraktionsniveau betrachtet werden und nicht die physikalische Struktur der Daten (wie z.B. unterschiedliche Dateiformate) als Grundlage der Modellierung verwendet wird. Als ideale Lösung bieten sich hier Abstrakte Datentypen (ADTs) an.


3.2. Abstrakte Datentypen (ADTs)

Abstrakte Datentypen beschreiben die Eigenschaften eines Datentyps mittels der auf ihm möglichen Operationen, ohne auf implementationsspezifische Details einzugehen. Die Eigenschaften der Operationen werden weiter durch Definitions- und Wertebereich sowie durch Axiome festgelegt. Diese Axiome stellen Bedingungen dar, die von den Operationen erfüllt werden müssen. Dabei sollte die Menge der Axiome vollständig (d.h. alle wichtigen Eigenschaften erfaßt) und möglichst klein sein (keine redundanten Axiome).

Das folgende Beispiel (Abb. x) zeigt einen ADT für eine Menge von Ganzzahlen. Unter sorts stehen die verwendeten Mengen (Ganzzahlen, boolsche Werte). Unter ops sind die Operationen mit Definitions- und Wertebereich angegeben (leere Menge erzeugen, Element einfügen, Element löschen,...), und unter axs sind schließlich die Axiome angegeben (hier nicht vollständig).


adt intset

sorts	intset, int, bool

ops	empty                   ->  intset
	insert:	  intset x int	->  intset
	delete:	  intset x int	->  intset
	contains: intset x int	->  bool
	isempty:  intset	->  bool

axs	isempty(empty)	        = true
	isempty(insert(x,i))	= false
	insert(insert(x,i),i)	= insert(x,i)
	contains(insert(x,i),i)	= true
	contains(insert(x,j),i)	= contains(x,i) (i!=j)
	...

end intset
Abb. 1: Beispiel für einen ADT

3.3. Klassen als Implementation von ADTs

Die während der Designphase gebildeten ADTs werden nun in sogenannten Klassen implementiert. Klassen sind mit benutzerdefinierten Typen in klassischen Programmiersprachen vergleichbar und stellen Bildungsvorschriften für Kategorien von Objekten dar, die von den Klassen gebildet werden können.

Im einzelnen besteht eine Klassendefinition aus Methoden und Instanzvariablen:

Die Methoden stellen die auf Objekten dieser Klasse möglichen Operationen dar und entsprechen somit bis zu einem gewissen Grad den Prozeduren und Funktionen der klassischen Sprachen. Sie unterteilen sich in private Methoden, die für den Benutzer der Klasse unsichtbar sind, und in öffentliche Methoden, die die Schnittstelle nach außen bilden und Implementationen der Operationen des zugehörigen ADTs sind.

In den Instanzvariablen wird der innere Zustand der Objekte gespeichert. Sie sind in der Regel wie die privaten Methoden in der Klasse gekapselt und nur über die öffentlichen Methoden ansprechbar.

Abb. 2: Bestandteile einer Klasse

3.3.1. Exemplarbildung

Wie schon erwähnt, können von Klassen beliebig viele Exemplare, die sogenannten Objekte, gebildet werden. Diesen Vorgang bezeichnet man als Exemplarbildung. Während die Klassen nur abstrakte Bildungsvorschriften sind, belegen die gebildeten Objekte zur Laufzeit des Programms einen Teil des Hauptspeichers. Sie ähneln somit den Variablen der prozeduralen Sprachen, sind aber wesentlich komplexere Einheiten, da sie auch die auf ihnen ausführbaren Operationen beinhalten.

Abbildung 3 stellt noch einmal den Zusammenhang zwischen ADT, Klasse und Objekt dar, indem drei verschiedene Implementationen des ADTs intset als Klassen erzeugt werden und von jeder dieser Klassen drei Objekte gebildet werden:

Abb. 3: ADT, Klasse und Objekt

Die Bildung von Objekten ist der eigentliche Zweck der Klassen, da die Klassen selbst nicht unmittelbar verwendet werde können, sondern nur die Eigenschaften ihrer Instanzen festlegen. Die Exemplarbildung stellt somit eine direkte Form der Wiederverwendung der definierten Klassen dar.

3.3.2. Vererbung

Das Erstellen von Klassen und die Exemplarbildung alleine reichen aber nicht aus, um die Ziele der Wiederverwendung vollständig zu erfüllen. Man benötigt eine Technik, die es einem erlaubt, vorhandene Klassen in veränderter oder unveränderter Form in neue Klassen zu übernehmen. Dieses Verfahren wird als Vererbung bezeichnet. Durch die Vererbung ist es möglich, Methoden und Daten aus einer vorhandenen Klasse in neuen Klassen wiederzuverwenden.

Eine Klasse, die von einer anderen Klasse erbt, wird als abgeleitete Klasse, Abkömmling oder Erbe bezeichnet. Die vererbende Klasse wird als Basisklasse oder Vorfahr bezeichnet.

Vererbung ist ein transitiver Prozeß, das heißt, eine abgeleitete Klasse vererbt die Methoden und Daten ihrer Basisklasse wiederum an ihre Erben weiter.

3.3.2.1. Einfache Vererbung
Jede objektorientierte Programmiersprache besitzt als grundlegende Vererbungsmethode die einfache Vererbung. Hierbei erbt eine abgeleitete Klasse Eigenschaften von genau einer Basisklasse:

Abb. 4: einfache Vererbung

Die Klasse POLYGON beinhaltet einige allgemeine Methoden und Daten bezüglich Vielecken, welche durch die Vererbung auf die Klasse RECHTECK, nun in dieser neuen Klasse benutzt werden können. Weiterhin können natürlich auch neue Methoden und Daten erstellt werden.

Die einzige Ausnahme in Eiffel bildet die create-Funktion, welche zum Erzeugen eines Objektes einer bestimmten Klasse dient und somit ihren Konstruktor darstellt.

Die geerbten Methoden und Daten können natürlich umdefiniert werden. Bezogen auf das obige Beispiel wäre eine Umdefinierung von umfang sinnvoll, da sich der Umfang eines Rechtecks sicherlich einfacher berechnen läßt als der Umfang eines beliebigen Polygons.

Allerdings darf eine gegebene Methode nicht beliebig umdefiniert werden: Die Syntax muß erhalten bleiben, nur Semantikänderungen sind erlaubt. Um zu verhindern, daß eine Methode versehentlich umdefiniert wird, muß eine Umdefinierung in Eiffel explizit bei der Klassendefinition angegeben werden.

Eine solche Umdefinierung bzw. Erweiterung von Methoden wird natürlich dann notwendig, wenn der Vorfahr eine abstrakte Klasse ist und eine Exemplarbildung der neuen Klasse möglich sein soll.

Abb. 5: Klassenhierarchie

Eine abstrakte Klasse ist eine Klasse von welcher sich keine Objekte bilden lassen (z.B. von der Klasse POLYGON). Eine solche Klasse beinhaltet mindestens eine Methode in der Teile als deferred gekennzeichnet sind; diese nicht näher spezifizierten Teile werden als pre- oder postcondition bezeichnet. Das heißt, die Methode bzw. die Klasse beschreibt nur den "groben" Umgang mit Objekten dieser Klasse, die endgültige Implementation dieser Methoden kann dann nur durch einen Abkömmling dieser Klasse erfolgen.

Die Definition einer abstrakten Klasse (in Eiffel) wird immer durch die Bezeichner deferred class eingeleitet.

Eine Klasse welche von einer abstrakten Klasse erbt und die als deferred gekennzeichneten Methoden nicht verändert, ist wiederum eine abstrakte Klasse.

Wie schon erwähnt, beschreibt eine Klasse die Implementation eines abstrakten Datentyps, eine abstrakte Klasse hingegen beschreibt eine Gruppe von ähnlichen Implementationen eines abstrakten Datentyps.

3.3.2.2. Mehrfachvererbung
Unter Mehrfachvererbung versteht man den Fall, daß eine abgeleitete Klasse im Gegensatz zur einfachen Vererbung mehrere Basisklassen besitzt. Eine solche Klasse besitzt somit alle Methoden und Daten der Basisklassen. Genau wie bei der einfachen Vererbung ist eine Umdefinierung von Methoden der Basisklasse möglich.

Abb. 6: Mehrfachvererbung

Bei Mehrfachvererbung kann allerdings noch der Fall der Namensgleichheit von Methoden oder Instanzvariablen der Basisklassen auftreten. Diese Namenskollision wird in Eiffel durch eine Umbenennung innerhalb der abgeleiteten Klasse gelöst, andernfalls würde der Compiler die Kompilation mit einer entsprechenden Fehlermeldung abbrechen. In manchen Sprachen wie z.B. C++ wird eine Namenskollision nicht vom Compiler beanstandet, hier muß dann allerdings beim Zugriff auf diese Methode oder Instanzvariable der Name der Basisklasse als Präfix hinzugefügt werden. In anderen Sprachen entscheidet der Compiler aufgrund der Struktur der vorhandenen Klassenhierarchie, welche Methode oder Instanzvariable benutzt wird. Dieses Verfahren birgt allerdings ein Risiko, denn beispielsweise müssen zwei Methoden, die den gleichen Namen haben, nicht unbedingt den gleichen Typ haben.

Ein Spezialfall der Mehrfachvererbung ist die sogenannte wiederholte Vererbung, hierbei ist eine Klasse mehrfacher, indirekter Erbe der gleichen Basisklasse.

Abb. 7: wiederholte Vererbung

In Eiffel wird dieses Problem folgendermaßen gehandhabt: Ist z.B. eine Methode entlang des Vererbungspfades umbenannt worden, so beinhaltet die abgeleitete Klasse den Code dieser Methode mehrfach, wurde eine Methode aber nicht umbenannt, so wird der Code nur einmal übernommen.

3.3.2.3. Selektive Vererbung
Normalerweise erbt eine Klasse alle Methoden und Daten der Basisklasse. Allerdings unterstützen einige wenige objektorientierte Programmiersprachen eine selektive Vererbung, hierbei hat der Programmierer die Möglichkeit, bestimmte Methoden oder Daten einer Klasse nicht weiterzuvererben. Nur ein Teil der Basisklasse wird somit weitervererbt.

In Eiffel ist eine selektive Vererbung jedoch nicht möglich.

3.3.3. Klassenbibliotheken

Das Ziel der Vererbung und der Erstellung von Klassen ist natürlich die Wiederverwendung. Die meisten objektorientierten Programmiersprachen bieten eine Standardbibliothek, welche durch die Erstellung neuer Klassen ausgebaut werden kann. Ebenso können natürlich auch eigenständige Klassenbibliotheken aufgebaut werden.

Um aber nun Klassen wiederverwenden zu können, muß die Bibliothek erst einmal durchsucht werden, um Klassen zu finden, welche den gewünschten Anforderungen am besten entsprechen.

Diese Suche wird im allgemeinen mit einem sogenannten class browser durchgeführt. Hierbei handelt es sich um ein Werkzeug, welches ebenso zur Auswahl bestimmter Klassen, wie auch zum Durchsuchen von Bibliotheken dient. Der class browser ermöglicht es dem Benutzer, sich durch die Vererbungshierarchie zu hangeln, Instanzvariablen und Methoden anzeigen zu lassen und in Erfahrung zu bringen, welche Klassen eine gegebene Nachricht verschicken oder empfangen können. Weiterhin können Klassen und Methoden auch bezogen auf ihre Funktion in mögliche Gruppen aufgeteilt werden, welche dann mit dem browser durchsucht werden können. Manche browser bieten die Möglichkeit einer Mehrfachansicht der Bibliothekstruktur, es können zum Beispiel Ansichten vom Benutzer definiert werden, welche speziell zu einem bestimmten Arbeitsgebiet passen.

Jedoch können bei einer Auswahl immer noch Unklarheiten auftreten, da beispielsweise nicht immer ersichtlich ist, welche Funktion bzw. Funktionalität eine abgeleitete Klasse gegenüber ihrer Basisklasse besitzt.

Die Methode des affinity browsing versucht dies zu kompensieren, indem nicht nur die Vererbungshierarchie berücksichtigt wird, sondern auch die Ähnlichkeit und die Funktion der Klassen beachtet wird. Der affinity browser kann somit einen noch besseren Überblick über eine Klassenbibliothek vermitteln.

Alle derzeitig erhältlichen Programmierumgebungen beinhalten keine extrem großen Klassenbibliotheken, somit läßt sich ein browser sehr gut einsetzten, aber je größer die Anzahl der Klassen wird, desto schwieriger und somit ineffizienter wird die Verwendung eines browsers.


4. Wiederverwendung in der Praxis

In der Praxis hat die Erstellung eines Programms, von welchem später Teile wiederverwendet werden sollen, natürlich einen erheblich größeren Zeitaufwand zur Folge. Das erste Problem ist es, eben diese Teile zu finden, welche in Zukunft vielleicht einmal verwendet werden können, dann müssen diese Teile entsprechend verallgemeinert werden, denn je abstrakter das Material ist, desto größter ist die Chance, daß man es in einem anderen Projekt wiederverwenden kann.

Der durch die Technik der Wiederverwendung gewonnene Zeitvorsprung geht somit zunächst einmal durch diesen Mehraufwand für die Verallgemeinerung wieder verloren. Dieser Mehraufwand führt demzufolge auch zu einem zusätzlichen Kapitalaufwand bei der Entwicklung von Software.

Um allerdings eine spätere Produktivitätssteigerung durch die Wiederverwendung zu erreichen sind diese Mehrkosten unvermeidlich. Der Gewinn bezüglich der einer effizienteren, d.h. wirtschaftlicheren Softwareentwicklung wird erst sichtbar, wenn ein bestimmtes Mindestmaß an Investitionen überschritten ist, also eine gewisse kritische Menge an wiederverwendbarem Material erzeugt wurde.

Hier spielt sich eine zur klassischen Industrialisierung analoge Entwicklung ab, bei der sich der Schwerpunkt der Herstellung von Produkten von einer traditionell arbeitsintensiven hin zu einer kapitalintensiven Tätigkeit verschiebt [2].


5. Schlußbemerkung

Zusammenfassend läßt sich sagen, daß der gezeigte objektorientierte Ansatz die zur Zeit effektivste Methode zur Unterstützung der Wiederverwendung darstellt.

Mit der zunehmenden Komplexität der Soft- und Hardware, besonders im Hinblick auf parallele Rechnersysteme, stellt sich jedoch die Frage, wie lange die Technik der objektorientierten Programmierung diese Vorrangstellung noch halten kann.

Wie schon angedeutet stellt die Suche nach geeigneten Klassen, welche für ein Projekt genutzt werden könnten, ein Problem dar. Die Fülle des vorhandenen Material wird immer größer und der Überblick geht immer mehr verloren.

Schon heute sind im Bereich der class browser Expertensysteme im Einsatz,

doch auch diese werden auf Dauer ihre Effizienz bezüglich der Klassenauswahl verlieren, wenn die Menge der wiederverwendbaren Software das "überschaubare Maß" überschreitet.

Die Vorrangstellung der objektorientierten Methode wird aber sicherlich noch viele Jahre aufrecht erhalten bleiben, doch irgendwann wird wieder ein Umdenken bei der Software-Erstellung nötig sein, vielleicht dann in Richtung von parallelen Rechnersystemen.



6. Literaturverzeichnis

[1] Meyer, Bertrand: Reusability: The Case for Object-Oriented Design.
IEEE Software, März 1987, S. 37-51

[2] Endres, A.: Software-Wiederverwendung: Ziele, Wege und Erfahrungen. Informatik-Spektrum 11 S. 85-95 (1988)

[3] Gibbs, S., Tsichritzis, D., Casais, E., Nierstrasz, O., Pintado, X.: Class management for software communities. Communications of the ACM Vol.33, No.9 (Sept. 1990)

[4] Korson, Tim und McGregor John D.: Understanding Object-Oriented: A Unifiying Paradigm. Communications of the ACM Vol.33, No.9 (Sept. 1990)


Frank Thilo - 16.8.95