Melden Sie sich hier an, um auf Kommentare und die Whitepaper-Datenbank zugreifen zu können.

Kein Log-In? Dann jetzt kostenlos registrieren.

Falls Sie Ihr Passwort vergessen haben, können Sie es hier per E-Mail anfordern.

Der Zugang zur Reseller Only!-Community ist registrierten Fachhändlern, Systemhäusern und Dienstleistern vorbehalten.

Registrieren Sie sich hier, um Zugang zu diesem Bereich zu beantragen. Die Freigabe Ihres Zugangs erfolgt nach Prüfung Ihrer Anmeldung durch die Redaktion.

21.05.1999 - 

Componentware

Softwarekomponenten als Hoffnungsträger

In der Softwarebranche kursieren seit einiger Zeit neue Reizworte: "Komponente" beziehungsweise "komponenten- basierende Anwendungsentwicklung". Damit sind Konzepte und Techniken gemeint, die den Weg zu einer wirklich industriellen Softwareproduktion ebnen helfen könnten. Frank Griffel* berichtet über den Stand der Diskussion.

Die Entwicklung von Software wird heute in erster Linie als kreativer Schaffensprozeß und nicht als ingenieursmäßiger Aufbau von Systemen verstanden. Hauptgrund dafür ist vor allem ein Mangel an Beurteilungsmaßstäben, Qualitätskriterien und längerfristig gültigen Basistechniken. Ein Vergleich zu anderen Industriezweigen läßt schnell deutlich werden, daß dort Standardisierung, Normierung, Klassifikation und exakte Maßstäbe die Grundpfeiler einer hohen Produktivität bilden.

Interessant daran sind weniger das Entstehen von fertigen Endprodukten, sondern insbesondere die zahlreichen Zwischenprodukte, die in vielfältiger Weise in weiterführende Produktionsketten einfließen. Und hier schließlich schaut so mancher Entwicklungsleiter der Softwarebranche neidvoll auf die anderen Branchen: Könnte nicht auch sein Programmiererteam auf fertige Einzelteile zurückgreifen, die nur noch an die vorgegebenen Randbedingungen des eigenen Projekts angepaßt und zur gewünschten Anwendung zusammengefügt werden müssen?

In der Praxis ist die Erfindung des Rades durch jeden einzelnen Programmierer immer noch häufig genug in frühen Projektphasen zu beobachten. Viele Details der Programmierung - von Speicherverwaltung über Datei-Ein/Ausgabe bis zur GUI-Gestaltung - entwickeln sich rasch zu Nebenkriegsschauplätzen der Anwendungsentwicklung. Dabei sollte sich diese doch eigentlich auf die Lösung des "fachlichen", das heißt zum Beispiel branchen- beziehungsweise anwenderspezifischen Problems konzentrieren. Gegen die Beschäftigung mit allzu detaillierten Programmierproblemen spricht zudem die große Komplexität vieler DV-Anwendungen, die eher ein Augenmerk auf das Zusammenspiel eigenständiger Funktionseinheiten benötigen, als auf deren Interna. Nun sind diese Probleme und Erkenntnisse zwar nicht neu, doch noch immer zu wenig in den Köpfen so mancher Entscheider und Programmierer verankert. Was also hat die Softwaretechnik bislang als Lösung anzubieten?

Das leistungsfähigste Instrument ist heute sicherlich die Objektorientierung, ihre methodischen Vorgehensweisen und zugehörigen Konzepte wie Entwurfsmuster und Rahmenwerke (Frameworks). Objekte selbst bieten sich zum einen als abgrenzbare Abstraktion bestimmter Programmfunktionen an. Zum anderen fungieren sie als eingängige Modellierung realer Gegebenheiten, indem sie als klassifizierbare, aber individuelle Einheiten zum Beispiel eine direkte Abbildung zu bearbeitender Daten oder Aufgaben erlauben. Damit scheint eine der ersten obengenannten Anforderungen erfüllt: Es liegt ein Konzept vor, das es erlaubt, einzelne, "fertige" Bausteine zur Anwendungsentwicklung bereitzustellen. Eine Wieder- beziehungsweise Weiterverwendung solcher Teillösungen erscheint sinnvoll.

Design pattern helfen abstrahieren

Nach der ersten Euphorie unter den Vertretern der Objektorientierung ist allerdings auch rasch die Forderung nach mehr Abstraktion aufgekommen. Wird nämlich ein komplexes Softwaresystem auf der Ebene einzelner programmiersprachlicher Objekte als Konglomerat von Basisbausteine betrachtet, ergibt sich eben in der Praxis dann doch kein übergreifendes, wiederverwendbares Verständnis für eine Softwarelösung.

Einen richtungsweisenden Schritt stellt hier die Etablierung sogenannter Entwurfsmuster (design patterns) dar. Ein solches Muster erlaubt es Entwicklern, ihre Programmstrukturen abstrakter und allgemeiner zu beschreiben, das heißt über sie zu "sprechen", ohne gleich programmiertechnische Details einzelner Objekte darstellen zu müssen. Auf diese Weise ist insbesondere ein Vergleich verschiedener Systeme möglich, selbst wenn diese mit unterschiedlichen Techniken realisiert wurden.

Insofern stellen Entwurfsmuster also einen gewissen Grad der eingangs geforderten Normierung und Maßstäbe bereit. Die Objektorientierung bietet heute insbesondere für die Entwicklungsphasen "Analyse" und "Design" mächtige und wirkungsvolle Instrumente, die auch bei der Erstellung von Software ein geplantes, ingenieurmäßiges Vorgehen unterstützen.

Der Übergang in die Implementationsphase wirft allerdings erneut Probleme auf, da die in Analyse und Design gewonnenen Abstraktionen nun doch - und das meistens sehr direkt - auf eine programmiersprachliche Ebene heruntergebrochen werden.

Um auch diesen Übergang besser zu unterstützen, bietet die objektorientierte Sicht das Konzept von Rahmenwerken an. Diese stellen in der Regel eine wohldurchdachte und strukturierte Sammlung von Klassenhierarchien dar, also einen bereits fertigen Programmcode, der zu seiner Nutzung lediglich noch instanziert werden muß. Auf diese Weise kann ein Anwendungsentwickler einerseits auf bestehendes Designwissen zurückgreifen - es ist in der Struktur des Rahmenwerkes impliziert -, andererseits kann er auch Teillösungen in Form der vorhandenen Klassen zum Einsatz bringen. Dabei wird ihm zugleich ein Leitfaden an die Hand gegeben, wie eine sinnvolle Kombination der bereitgestellten Einzelteile aussehen könnte - nämlich wiederum implizit durch die hierarchischen Abhängigkeiten des Frameworks. Viele programmtechnische Details können in den Einzelklassen eines Rahmenwerkes verborgen werden, ohne daß ein Anwendungsentwickler jemals mit ihnen konfrontiert wird und vor allem ohne daß er sie selbst "erfinden" muß.

Frameworks entlasten den Anwendungsentwickler

Auf diese Weise gelingen scheinbar auch für die Implementationsphase die gewünschte Abstraktion und zugleich die Konzentration auf die fachlich, das heißt aus dem Anwendungskontext entstehenden Probleme. Hierzu trägt auch bei, daß für unterschiedliche Anwendungsbereiche jeweils eigene, spezifische Rahmenwerke bereitgestellt werden können. Das Konzept "Objekt" und die damit verbundenen Ideen scheinen also die Möglichkeiten und Voraussetzungen einer industriellen Softwareproduktion zu bieten.

Warum also das zur Zeit ständig zunehmende Interesse am Begriff der "Komponente"? Zunächst läßt sich festhalten, daß sich die Antwort auf diese Frage nahtlos in die obige Darstellung der Objektorientierung einreihen läßt: Es geht einmal mehr darum, eine höhere (bessere?) Abstraktion bei der Behandlung von Softwaresystemen zu erreichen. Der Umgang mit objektorientierten Ansätzen in der Entwicklungspraxis hat - insbesondere in der Phase der Implementation - gezeigt, daß sich die Produktivität in der Software-Entwicklung offenbar doch nicht in dem erhofften Maße steigern läßt. Objekte (beziehungsweise deren Klassen) sind häufig nicht wiederverwendbar, weil sie zu spezifisch entworfen und zu "fein" in ihrer Granularität sind, das heißt, sie sind zu stark auf den Problemteil fokussiert, den sie mit ihrer eigenständigen Funktionalität adressieren.

Frameworks sind aufgrund ihres Umfangs häufig komplex zu erlernen - ungleich schwerer ist die Erstellung eines gut durchdachten Rahmenwerks. Dies hat zur Folge, daß deren erfolgreicher Einsatz mit ihrer vorhandenen Anzahl steht und fällt. Solche Klassenhierarchien beinhalten oftmals versteckte Abhängigkeiten, die in der Praxis doch wieder die Veränderung eines schon als fertig erachteten Codes erfordern. Theoretische Probleme wirken sich auch in der Praxis aus. Zu ihnen zählen "Vererbungsanomalien", also undefiniertes oder falsch spezifiziertes Programmverhalten, das sich aus den Vererbungsbeziehungen zwischen Klassen ergibt. Ein weiteres Beispiel sind "brüchige Basisklassen". Diese bedeuten, daß notwendige Veränderungen einzelner Klassen möglicherweise Änderungen aller von ihnen abhängigen Klassen bedingen. Diese Probleme der praktischen Anwendung zeigen deutlich, daß die Objektorientierung erst allmählich Einzug in aktuelle deutsche Softwareprojekte hält.

Dieses zähe Vorankommen hat zwei Ursachen: Zum einen ist eine objektorientierte Denkweise nicht von heute auf morgen erlernbar, und noch immer bestimmt die Altlastenpflege das Tagesgeschäft der Entwicklungsabteilungen. Zum anderen nehmen so manche Projektleiter und Entscheider die Ideen der Entwickler nicht ernst. Gerade bei dieser Klientel fällt die Komponentensicht auf fruchtbaren Boden, verspricht sie doch die wirkliche Lösung der Produktivitätskrise, ohne gleich mit ganzen Aktenordnern voll von neuen Forschungsergebnissen zu drohen.

Dies wird dadurch gefördert, daß es keine klare Definition darüber gibt, was eigentlich genau eine Softwarekomponente ist. Wem Freiraum für eine eigene Interpretation bleibt, der greift ein neues Konzept gerne auf. Zudem stehen ohnehin brennende Fragen heutiger IT-Strukturen offenbar im Mittelpunkt des Komponententrends: Verteilung, Interoperabilität und Integration stehen ebenso wie die schnelle Prototypenentwicklung (rapid prototyping) und die Analyse bestehender Systeme (reverse engineering) auf der Tagesordnung jeder Komponentendiskussion.

Und in der Tat steht hinter dem Wunsch einer komponentenbasierenden Softwareprogrammierung heute nicht mehr die Entwicklung von Benutzeroberflächen (GUIs) und integrierten Dokumentensichten (Verbunddokumente), sondern die Handhabung komplexer, großer IT-Systeme in modernen, vernetzten Umgebungen. Dabei steht gar nicht einmal der traditionelle Modularisierungsansatz zur Komplexitätsreduktion im Vordergrund, sondern entscheidend ist der Integrationsaspekt.

Aussagekräftigere Schnittstellen

Eine Software-Entwicklung, die auf Mechanismen zur "Komposition" bestehender Einzelteile beruht, umfaßt das Integrationsproblem gewissermaßen implizit: Zu verbindende Einzelfunktionalitäten können ebenso Neuentwicklungen auf Basis unterschiedlicher Technologien sein wie auch ältere, bestehende Anwendungen. Eine Integrationsfähigkeit beruht fast immer auf der Grundvoraussetzung der Interoperabilität: Einzelne Anwendungsbausteine müssen überhaupt in der Lage sein, Daten sinnvoll auszutauschen und gegenseitig bereitgestellte Funktionen zu nutzen. Wird die Komponentensicht auf diese Aspekte begrenzt, liefert sie in der Tat einen hohen Abstraktionsgrad für Software. Dann nämlich rücken andere Fragen der Spezifikation von Schnittstellen, also der Verbindungspunkte oder -flächen, die Frage der Aggrega- tion, das heißt der konsistenten Bildung größerer Einheiten, und die Frage der Komposition, also des Zusammenfügen der einzelnen Teile in den Vordergrund. Die Realisierung ihrer einzelnen Funktionen wird zweitrangig. Naturgemäß ergeben sich dabei aber zunächst die gleichen Probleme wie bei der Objektsicht, denn auch die impliziten Details einer Komponentenimplementation können sich nach außen auswirken und eine problemlose "Komposition" vereiteln.

Der Komponentenansatz versucht, hier durch verbesserte, semantisch reichere, das heißt inhaltlich aussagekräftigere Schnittstellenbeschreibungen vorzubeugen. Ebenso soll die zur Zeit favorisierte Sicht auf eine Softwarekomponente als binäre, abgeschlossene Black-Box zur Vermeidung von Problemen bei ihrer Verwendung beitragen. Aus dieser Perspektive stellt eine Komponente ein ausführbares Stück Programmcode dar, dessen Interna dem Entwickler verborgen bleiben. Er kann (und soll) sich einzig auf die ihm präsentierte Spezifikation der Syntax und Semantik, also der Schnittstelle und des Verhaltens einer Komponente, verlassen.

Zur Flexibilisierung und Erweiterung der Einsatzmöglichkeiten beziehungsweise der Wiederverwendbarkeit sieht ein solches Komponentenmodell dann explizite Variationspunkte einer Komponente vor. Diese sind gewissermaßen vom Komponentenhersteller vorgesehene "Einstellungsmöglichkeiten" einer Komponente, die dem Anwendungsentwickler später die Anpassung des Bausteins an seine konkreten Bedürfnisse erlauben. Allerdings kann dies dann nur in einem gewissen Rahmen geschehen, den der Komponentenhersteller vorgegeben hat, so daß er auch Fehler ausschließen beziehungsweise bestimmte Garantien über seine Komponente geben kann. Dies ist in der Komponentensicht um so wichtiger, als ein Anwendungsentwickler sich auf die von ihm verwendeten Basisbausteine verlassen können muß, wenn er daraus komplexe Systeme zusammenstellen will.

Hier stellt sich erneut die Frage nach der Qualität, denn auch in einer Komponentensicht bleibt Software etwas sehr schwer und oft nur subjektiv Meßbares. Die dargestellte starke Kapselung kann aber zumindest helfen, Fehlinterpretationen und fehlerhaften Einsatz zu vermeiden. Weder kann der Quellcode verändert, noch können verwendete Algorithmen durch eigene ersetzt werden. Ein Baustein muß so akzeptiert werden, wie er angeboten wird. Denkbar ist dann das Szenario eines freien "Komponentenmarkts", etwa im Internet, aus dem ein Entwickler aussucht, was er benötigt, und in dem durch Konkurrenz Qualität entsteht.

Das Thema Qualität führt allerdings auch zu einem anderen, gegenteiligen Aspekt der Komponentensicht: der Wegwerf-Software. Gelingt es, Techniken und Entwicklungsmethoden bereitzustellen, die eine weitgehend problemlose Interoperabilität integrierbarer Einzelkomponenten erlauben, so liegt der Standpunkt nahe, eine "Quick-&-dirty-Programmierung" zu favorisieren. Wenn diese dann "mal eben" zu einer Anwendung zusammengeschaltet werden können, spart dies teure Entwicklerzeit und führt zu einem raschen Ausstoß fertiger Anwendungen. Mit dem Argument, daß vielen Softwaresystemen - gerade solchen im unternehmensinternen Einsatz - heute ohnehin nur eine kurze Lebensdauer vorausgesagt wird, spielt dieser "Wegwerf"-Aspekt in der Tat eine wesentliche Rolle in einem Teil des Lagers der Komponentenvertreter.

Daher erleben auch Skriptsprachen neuen Auftrieb, die eine einfache, meist interpretierte "Programmierung" des "Skeletts" einer komponentenbasierten Anwendung schnell und formlos erlauben. Das Skelett selbst bildet dann lediglich ein koordinierendes Gerüst der in Form von Komponenten "eingeklinkten" Einzelfunktionalitäten, ohne selbst wirkliche Funktionen zu enthalten. Hinzu kommt, daß der wünschenswerte Aspekt der Wiederverwendung, ähnlich dem obengenannten Problem von Rahmenwerken, erst dann zum Tragen kommen kann, wenn es ein genügend großes Angebot an guten Komponenten gibt. Vor allem aber sind Komponenten ihrerseits auf gewisse "Rahmenbedingungen", sprich Technologien, angewiesen, die im zweiten Teil des Beitrags (siehe Seite 22) erörtert werden.

*Frank Griffel ist wissenschaftlicher Mitarbeiter der Arbeitsgruppe "Verteilte Systeme" an der Universität Hamburg.