Software-Wiederverwendung (Reuse)
Geschwurbel von Daniel Schwamm (25.06.1994 bis 27.06.1994)
Inhalt
Der Begriff Software-Wiederverwendung (SW-Reuse) wurde vor ca. 25
Jahren geprägt und steht im Zusammenhang mit den Begriffen Software-Krise
und Software-Engineering. Die Software-Krise ist eine Folge des Auseinanderklaffens von
Angebot und Nachfrage von Software. Die Nachfrage wuchs überproportional, weil
die Hardware schneller an Komplexität und Leistung gewann, als die Software abzudecken
vermochte; und auch wenn die Software allen Anforderungen gerecht wurde, so war sie
doch meist zu komplex, um noch wartbar zu sein. Das Software-Engineering bot einen
Lösungsansatz zur Überwindung der Software-Krise. Statt Individualistentum
beim Programmieren wurde ein planbares, messbares (d.h. ingenieurhaftes)
Vorgehen in kleinen überschaubaren Schritten propagiert. Durch das
Software-Engineering verspricht man sich eine Steigerung der Qualität der Software.
Ausserdem sollen zukünftige Erweiterungen leichter möglich sein.
Es umfasst die Gebiete: Phasenmodelle, Prototyping,
Benutzeroberfläche, Qualitätssicherung von Entwicklungsprozess
und Endprodukt, und Reuse.
Die Idee der Software-IC (Integrated Circuit) als Analogon zu den Standardschaltkreisen
der Hardware wurde von Douglas McIlroy vorgeschlagen. Zunächst bezog sich dieses
Vorhaben nur auf den Source-Code der Software, doch inzwischen wird Reuse mithilfe
von ICs in allen Entwicklungsphasen betrieben. Gerade bei den frühen
Phasen (Analyse und Design) kann erkannt werden, welche Ergebnisse frühere
Entwicklungen wiederverwendet werden können.
Reuse soll die Produktivität steigern (indem man sich nur
auf das Wesentliche, d.h. das Neue beschränken kann, wird die
Entwicklungszeit reduziert) und die Qualität von Software(-Teilen) steigern.
Dadurch erhofft man sich - nicht unbedingt auf das einzelne Projekt bezogene -
allgemeine Kosteneinsparungen. Weitere positive Nebeneffekte der
Software-Wiederverwendung sind: Die Wartbarkeit der Software wächst, weil die
Software-ICs bekannt und geprüft sind, und Erfahrung kann z.B. in Form von
Klassenbibliotheken systematisch weitergegeben werden.
Grundbegriffe der Software-Wiederverwendung sind:
-
Software-Bausteine: Dazu gehören textuelle Beschreibungen,
formale Spezifikationen, grafische Entwürfe, Pseudocodevergabe,
Testfälle, Manuals, ...
-
Design for Reuse: Bereits beim Entwurf sollte Reuse
berücksichtigt werden. Es bedeutet zusätzlichen Entwicklungsaufwand,
um projektbezogene Lösungsansätze zu allgemein verwendbaren
Lösungsansätzen zu erweitern.
-
Recover for Reuse: Vorhandene Software-Bausteine neu aufspüren,
um sie zu wiederverwendbaren Software-ICs zu gestalten, wobei Reengineering-Techniken
eingesetzt werden können.
-
Black-Box-Reuse: Software-ICs sind ohne Detailkenntnis wiederverwendbar.
-
White-Box-Reuse: Software-ICs sind nur wiederverwendbar, wenn eine
Anpassung an ihnen vorgenommen wird, wozu ihr innerer Aufbau bekannt sein
muss.
-
Software-Beschreibung: Sie sollte Suchinformationen (Deskriptoren (Bezeichner),
Beziehungen zu anderen ICs und Klassifikationen) enthalten, um darüber ICs
über diverse Werkzeuge (z.B. Information Retrieval Systems) wieder
auffinden zu können.
-
IC-Bibliothek: Hiermit werden ICs nach vorgegebenen Schemata
klassifiziert und (mit einer kurzen Beschreibung) physikalisch gespeichert.
Trotz der aufgezeigten Vorteile, wird Reuse noch nicht
allgemein verwendet. Warum? Das Konzept ist doch bereits 25 Jahre alt. Im
Folgenden werden wir uns die technischen, aber auch v.a. die nicht-technischen
Problemfelder des Reuse betrachten. Im nächsten Kapitel sehen wir dann, in
wie weit sich die hier dargelegten Problemfelder bearbeiten lassen.
Die nicht-technischen Problemfelder der Software-Wiederverwendung sind:
-
Psychologische Barrieren: Software-Entwickler sehen sich als
Künstler, denen eine inhärente Skepsis gegen alles Fremde innewohnt,
und die auch aus ästhetischen Gründen Eigenes gegenüber Fremdem
bevorzugen (Not Invented Here Syndrome). Der Suchaufwand nach den
passenden ICs darf nicht unterschätzt werden, zumal der Erfolg keinesfalls
gesichert ist. Zudem werden IC-gebaute Programme meist grösser und
schwerfälliger, als wenn direkt anwendungsspezifische Bausteine verwendet
werden würden - und das sind natürlich weniger beliebte Eigenschaften von
Software.
-
Wirtschaftliche Barrieren: Reuse zahlt sich meist nur
langfristig aus. Zunächst müssen extra Software-ICs entwickelt werden,
die für ein Software-Projekt zusätzlichen und u.U. auch kostspieligen Mehraufwand
bedeuten können. Es kommt zum Konflikt zwischen globaler und lokaler Optimierung. Und
wer kann es schon einem unter Zeit- und Erfolgsdruck stehenden Projektleiter
übel nehmen, wenn er eher lokal, statt global optimiert?
Reuse verlangt zunächst einige Investitionen, vor denen so manches Unternehmen
zurückscheut. Es müssen CASE-Tools (Computer-Aided Software Engineering) und
Klassenbibliotheken angeschafft werden, und zudem eine Informationsinfrastruktur
und Schulungsmöglichkeiten zur Verfügung stehen.
-
Juristische Barrieren: Reuse (von Fremdsoftware) wirft rechtliche Probleme
auf, die das Urheberrecht und Haftungsregelungen betreffen.
-
Organisatorische Barrieren: Wer baut die unternehmensweite Infrastruktur auf,
die Reuse unterstützt? Für die Software-Wiederverwendung müssen diverse
Verantwortlichkeiten festgelegt, Organisatoren gefunden, Belohnungssysteme
installiert und nicht zuletzt passende Werkzeuge beschafft werden.
Wie integriert man Reuse harmonisch in die einzelnen Phasen
des Entwicklungsprozesses, sodass möglichst viele Software-ICs
wiederverwendet bzw. möglichst viele neue Software-ICs erstellt werden? Folgende
Problembereiche müssen abgedeckt werden:
-
Identifikation der ICs (Domain Analysis): Das Potenzial
der Wiederverwendung bzgl. einer Software ist schwer abzuschätzen, hängt
aber damit zusammen, welche Funktionen sie anbietet. Welche Funktionen sollen
dazu aber in welche ICs gepackt werden? Ein methodisches Vorgehen hierzu werden
wir später kennenlernen.
-
IC-Qualität: Wie können die nötigen Anforderungen durch Software-Engineering
erfüllt werden?
-
IC-Verwaltung und Suchunterstützung: Unternehmensweite Datenmodelle sind nötig,
eine umfassende Infrastruktur zu errichten. Wie können ICs am besten beschrieben werden,
wie lassen sie sich zum Zwecke der Wiederverwendung finden?
Reuse muss in das Zielsystem des Unternehmens aufgenommen
werden. Manager haben es ausdrücklich zu fördern; sie müssen die
Reuse-Programme steuern. Doch nur in den Projekten selbst kann die nötige
Detailarbeit vorgenommen werden, die entsprechend vom Management zu
unterstützen ist. Dazu sind zunächst umfangreiche Investitionen von
Nöten, z.B. müssen Reuse-Werkzeuge und Belohnungssysteme eingerichtet
werden. Die wirtschaftlichen Barrieren müssen gebrochen werden, ebenso die
psychologischen Barrieren, z.B. durch reuse-motivierende Führung.
Die quantitative Erfolgskontrolle kann Ergebnisse liefern, die als Basis
von Belohnungssystemen fungieren können. Über Software-Metriken (Kennzahlen)
kann festgestellt werden, inwieweit sich die Nutzung von Software-ICs gegenüber der
Entwicklung von neuer Software langfristig wirtschaftlich rechnet. Die Metriken dazu
sollten leicht zu realisieren sein, aber dennoch aussagekräftig sein, die
Erhebung der Daten vollständig und korrekt.
-
Metriken für ICs: Erfasst werden v.a. der Erstellungsaufwand und die Zahl
der Nutzungen der ICs. Beispiels für solche Metriken sind:
-
Shipped Source Instruction: Anzahl der Programmzeilen
eines Software-ICs (ohne Kommentare).
-
Reuse Frequency (RF): Anzahl der Nutzungen der ICs durch Fremde/Externe.
-
Part Value: Reuse-Wert eines ICs = SSI(IC) * RF(IC).
-
Metriken für IC-Nutzung: Erfasst wird hier die Einsparung durch Reuse
gegenüber Neuentwicklung. Ausgangsbasis: Reuse veranschlagt nur 20% der
normalen Herstellungskosten. Beispiele:
-
Reuse Source instruction (RSI): Zahl der Fremdzeilen in einem Software-IC.
-
Grad des Reuse: Summe( RSI(IC) ) / Summe( SSI(IC) )
Belohnungssysteme (Incentives) sind extrinsische Motivatoren
für die Software-Entwickler, um Reuse zu betreiben. Die Belohnung ist gedacht
als Ausgleich für den Mehraufwand, den die Software-Wiederverwendung verursacht.
Als Basis dienen die Ergebnisse der quantitativen Erfolgskontrolle, wie sie die
Reuse-Metriken liefern.
-
Belohnung für die IC-Hersteller: Unterscheiden werden
die Belohnungsformen Initialisierungsbelohnung (generelle Belohnung für das Beachten
von Reuse-Optionen), die Popularitätsbelohnung (abhängig davon, wie weit die
Software-ICs Wiederverwendung gefunden haben) und Qualitätsbelohnungen.
Häufig wird die Gesamtbelohnung über Punktesysteme ermittelt, die
eine Gewichtung der einzelnen Belohnungsformen erlauben.
-
Belohnung für die IC-Nutzer: Um Reuse zu initialisieren, kann die Verwendung
von Software-ICs durch Belohnungen honoriert werden. Bei etablierten
Reuse-Programmen können jedoch den Nutzern der ICs u.U. sogar Kosten für
die Nutzung fremder ICs in Rechnung gestellt werden.
Folgende Aspekte sind bei Einrichtung eines Reuse-Programms zu beachten:
-
Top-down- oder Bottom-up-Initiierung:
Top-down-Einführung bedeutet, dass das Management Direktiven ausgibt,
wie Reuse im Unternehmen zu betreiben ist. Aufgrund der Komplexität und
Risikogefahr von Software-Wiederverwendung - möglicherweise bringt es aus
irgendwelchen Gründen gar keine Kostenvorteile - ist von diesem Vorgehen
abzuraten. Besser ist eine Bottom-up-Initiierung; das Reuse-Programm soll
evolutionär wachsen, sich Trial-and-Error durchsetzen.
-
Zentrale oder dezentrale Bibliotheken: In Unternehmen mit
Mainframe-Dominanz können zentrale Bibliotheken verwendet werden, die
sämtliche Software-ICs in einheitlicher, konsistenter Form verwalten. Dazu
muss man jedoch eine Administrationsgruppe bilden, die die Wartung der
Zentralbibliothek übernimmt. Bei dezentralen, verteilten Bibliotheken
vermisst man den übergreifenden Charakter der Software-ICs, zumindest
kann er leicht verloren gehen. Am günstigsten sind wohl hierarchisierte
Bibliotheken, die auf Server und Mainframes laufen, und über ein LAN in
Verbindung stehen.
-
Auswahl der Entwurfsmethodik, Werkzeuge, Erfolgskontrolle und Belohnungssysteme.
-
Festlegung der Verantwortlichkeiten: Es können
Reuse-Teams (Koordinateure), IC-Teams (Hersteller), Bibliotheken-Teams
(Administratoren) und Gutachter-Teams (Metriken-Prüfer) gebildet werden.
-
Durchführung von Schulungsmassnahmen: Diese soll die Mitarbeiter mit
Reuse-Verfahren vertraut machen und psychologische Barrieren aufbrechen.
Beispiele für erfolgreiche Ansätze von Software-Wiederverwendung sind:
-
Funktionsbibliothek: Sammlung von Black-Box-Funktionen, die mit einer
funktionsorientierten Programmiersprache angefertigt wurden. Eine nachträgliche
Änderung ist kaum möglich. Beispiel: SPSS (Funktionen für Statistik), IMSL
(Funktionen für Numerik).
-
Software-Schablonen: Rahmenprogramme, die durch Code aufzufüllen sind.
Ein White-Box-Vorgehen mit anschliessenden Tests ist nötig. Der Reuse-Gedanke
wird nur bei der Implementierung berücksichtigt.
-
Generatoren: Eingegeben wird, WAS man haben will, und der Generator
gestaltet daraus das WIE. Dieses Black-Box-Vorgehen funktioniert nur auf eng
umrissenen Gebieten (wie z.B. grafische Oberflächen), ist dort aber sehr effektiv.
Beispiel: Visual Basic.
-
Abstrakte Datentypen: Dies sind benutzerdefinierte Typen, die eingekapselt
als Module vorliegen. Dem User wird nur eine Operationsschnittstelle angeboten
(Black-Box), über die er die abstrakten Datentypen bearbeiten kann. Beispiele:
Ada, Modula, OOP (objektorientierte Programmierung).
-
Objektorientierung: Die Objektorientierung umfasst abstrakte Datentypen,
aber die Software-Wiederverwendung betrifft hier sämtliche Phasen des
Entwicklungsprozesses (z.B. abstrakte Typen als Analyse- und Designobjekte).
Dabei kann Black-Box-Reuse genauso wie White-Box-Reuse (durch Vererbung und
Überladung) betrieben werden. Die statische Typenkontrolle kann durch Polymorphismus
abgeschwächt werden, wodurch eine späte Bindung erfolgt, die die Klassen allgemeiner
erweiterbar und nutzbar macht. Generische Klassen vergrössern ebenfalls den Spielraum
für den Benutzer. Bibliotheken bieten eine einheitliche Entwurfsphilosophie. Und die
Object Management Group (OMG) sorgt für Standards.
-
Anwendungsarchitekturen: Hier werden enge Anwendungsgebiete vollständig
mit Software-ICs abgedeckt. Wie ein Puzzle müssen die ICs einen vorgegeben
Rahmen - ähnlich den Software-Schablonen - ausfüllen. Die Architektur (der Rahmen)
muss als White-Box gesehen werden, während die ICs selbst Black-Boxes sind.
Klassische Entwicklungsprozessmodelle sind Wasserfallmodelle bzw. - falls sie
iterativ sind - Spiralenmodelle. Betrachten wir einmal, wie das Reuse in solchen
Entwicklungsprozessen integriert werden kann.
-
Domain Analysis: Hierbei handelt es sich um eine Phase vor den
konventionellen Phasen der Software-Entwicklung, die unabhängig vom späteren
konkreten Programm sein soll. Dazu werden alle für ein Anwendungsmodell
relevanten Software-ICs entworfen. Betrifft dies nur ein Gebiet, spricht man
von vertikaler, ansonsten von horizontaler Domain Analysis. Die Domain
Analysis besteht aus den Schritten:
-
Project Planning: Informationsquellen aufspüren, Machbarkeitsstudie durchführen.
-
Data Collection: Wissenserwerb, z.B. über Reengineering (altes Wissen
herausfiltern), Interviews und Fragebögen.
-
Data Analysis: Prüfung der Vollständigkeit der ICs für das Anwendungsmodell,
welches sich u.U. zu einer Anwendungsarchitektur erweitern lässt. Werkzeuge:
Strukturierte Analyse, OOA (objektorientierte Analyse). Dabei sind Trade-offs
(Unvereinbarkeiten) zwischen ICs, die die Architekturen spalten können, zu vermeiden.
-
Klassifikation: Clusterbildung über ICs und abstrakte Beschreibungen vornehmen.
-
Evaluation: Bewertung und Prüfung des Anwendungsmodells.
-
Reuse in den einzelnen Phasen des Entwicklungsprozesses:
In jeder Phase (Analyse, Design, Implementierung, Test und Wartung) sind die
Ergebnisse der Domain Analysis zu berücksichtigen. Zusätzlich
muss am Anfang und Ende jeder Phase geprüft werden, ob und wie weit
sich alte ICs nutzen bzw. neue ICs entwickeln lassen, und wann
anwendungsspezifisch vorgegangen werden muss.
Gute allgemeine Qualitätskriterien für Software sind: Korrektheit, Robustheit,
Effizienz, Portabilität, Dokumentation und Modularität. Für das Reuse sind jedoch
noch weitere Qualitätskriterien sinnvoll, nämlich:
- Allgemeinheit
- Erweiterbarkeit/Anpassungsfähigkeit
- Integrierbarkeit und Kombinierbarkeit (Schnittstellenproblem)
- Selektierbarkeit (für die Kandidatenbestimmung)
- Verstehbarkeit (für die Kandidatenauswahl)
Die Beschreibung der ICs ist wichtig, weil über sie die gesammelten ICs selektiert,
bewertet und auf ihr Modifikationspotenzial abgeschätzt werden können.
-
Klassifikationen von Software-ICs: Die Beschreibung von Objekten
kann in Form von Klassifikationen erfolgen, wobei zwischen hierarchischer
Klassifikation (Bäume mit ICs als Blätter) und Facettenklassifikation
unterschieden wird. Bei hierarchischen Klassifikationen müssen ICs
über Navigationsverfahren gesucht werden, die zwar durch Expertensysteme
(XPS) unterstützt werden können, dennoch aber kein Potenzial zu einer
Ähnlichkeitssuche besitzen - es sei denn, man greift auf komplizierte
Querverweise zurück. Besser sind hier die Facettenklassifikationen,
die die ICs nach bestimmten Facetten (z.B. Qualität oder Geschwindigkeit)
Terme zuordnen können, die mit (Domain Analysis-genormten) Ausprägungen
gefüllt werden können. Information Retrieval Systeme (IRS) erlauben dann
anschliessend über die Eingabe von Deskriptoren - ähnlich wie bei der
Relationen-Algebra - das Finden von ICs, die in Form von Relationen
vorliegen können. Ein Konzeptgraph wird über die ICs gelegt, wobei
innere Knoten abstrakte Typen wiedergeben, die Terme die Blätter füllen
und die Kanten mit dem Grad der Ähnlichkeit gewichtet werden - der kürzeste
Pfad gibt also jeweils die grösste Ähnlichkeit zwischen zwei Termen an.
-
Textuelle Beschreibung: In meist natürlicher Sprache
können die oben genannten Facettenklassifikationen beschrieben werden,
entweder im Code selbst oder durch externe Dokumentation. Da String-Matching
die Suche bestimmt, bereiten Synonyme häufig Probleme. IRS gestatten automatisches
Indexing über Deskriptoren-Häufigkeiten. Diese Deskriptoren gestatten
ein späteres Parsing durch alle ICs. Eine invertierte Liste beschreibt,
wie oft welches Wort in welcher IC-Beschreibung vorkommt, oder gibt in
(komprimierten) Bit-Vektor-Listen an, ob sie in einer Mindestanzahl
vorkamen oder nicht.
-
Beziehungen zwischen den ICs: Die Beziehungsbeschreibung
trägt zur semantischen Beschreibung der ICs bei. Aggregations- und
Zerlegungsstrukturen (Dekomposition) werden hierzu genauso erfasst wie
Generalisierungsstrukturen bzw. Spezialisierungsstrukturen, Importdienste
bzw. Exportdienste sowie der Hinweis auf Versionen und Varianten eines
ICs. Die Vernetzten der ICs erlaubt ein kontextspezifisches Navigieren,
das über grafische Browser visualisiert werden kann.