Software-Wiederverwendung (Reuse)

Geschwurbel von Daniel Schwamm (25.06.1994 bis 27.06.1994)

Inhalt

1. Einführung

1.1. Anfänge der Software-Wiederverwendung

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.

1.2. 1.2 Motivation

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.

1.3. Grundbegriffe

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.

2. Problemfelder der Software-Wiederverwendung

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.

2.1. Nicht-technische Problemfelder

Die nicht-technischen Problemfelder der Software-Wiederverwendung sind:

  1. 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.
  2. 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.
  3. Juristische Barrieren: Reuse (von Fremdsoftware) wirft rechtliche Probleme auf, die das Urheberrecht und Haftungsregelungen betreffen.
  4. 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.

2.2. Technische Problemfelder

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:

  1. 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.
  2. IC-Qualität: Wie können die nötigen Anforderungen durch Software-Engineering erfüllt werden?
  3. 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?

3. Nicht-technische Aspekte des Reuse (Lösungsansätze)

3.1. Management-Unterstützung

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.

3.2. Erfolgskontrolle des Reuse (Measurement)

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.

  1. 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).
  2. 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) )

3.3. Belohnungssysteme

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.

  1. 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.
  2. 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.

3.4. Initiierung des Reuse-Programms

Folgende Aspekte sind bei Einrichtung eines Reuse-Programms zu beachten:

  1. 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.
  2. 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.
  3. Auswahl der Entwurfsmethodik, Werkzeuge, Erfolgskontrolle und Belohnungssysteme.
  4. Festlegung der Verantwortlichkeiten: Es können Reuse-Teams (Koordinateure), IC-Teams (Hersteller), Bibliotheken-Teams (Administratoren) und Gutachter-Teams (Metriken-Prüfer) gebildet werden.
  5. Durchführung von Schulungsmassnahmen: Diese soll die Mitarbeiter mit Reuse-Verfahren vertraut machen und psychologische Barrieren aufbrechen.

4. Technische Aspekte des Reuse (Lösungsansätze)

4.1. Erfolgreiche Ansätze des Reuse

Beispiele für erfolgreiche Ansätze von Software-Wiederverwendung sind:

  1. 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).
  2. 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.
  3. 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.
  4. 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).
  5. 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.
  6. 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.

4.2. Entwicklungsprozessmodell

Klassische Entwicklungsprozessmodelle sind Wasserfallmodelle bzw. - falls sie iterativ sind - Spiralenmodelle. Betrachten wir einmal, wie das Reuse in solchen Entwicklungsprozessen integriert werden kann.

  1. 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.
  2. 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.

4.3. Qualitätskriterien für Bausteine

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)

4.4. IC-Beschreibung und Suchverfahren

Die Beschreibung der ICs ist wichtig, weil über sie die gesammelten ICs selektiert, bewertet und auf ihr Modifikationspotenzial abgeschätzt werden können.

  1. 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.
  2. 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.
  3. 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.