Web

Aspektorientiert bis eXtrem - Trends im Software-Engineering

12.03.2001
Objektorientierte und komponentenbasierte Entwicklung haben sich durchgesetzt. So wundert es nicht, dass zunehmend Begriffe auftauchen, die für neue Ansätze stehen. Dazu zählen die aspektorientierte, generische und generative Programmierung, Intentional und eXtreme Programming sowie Software-Produktlinien.

MÜNCHEN (COMPUTERWOCHE) - Die objektorientierte und die komponentenbasierte Softwareentwicklung haben sich weitgehend durchgesetzt, und so wundert es nicht, dass zunehmend Begriffe auftauchen, die für neue Ansätze zur Programmierung stehen. Dazu zählen die aspektorientierte, generische und generative Programmierung, Intentional und eXtreme Programming sowie Software-Produktlinien. Ulrich Eisenecker* gibt einen Überblick über diese neuen Methodiken.

Es ist eine alte Erfahrung, dass trotz aller Bemühungen bestimmte Teile eines Programms nicht "sauber" in Klassen oder Funktionen verpackt werden können. Dies gilt beispielsweise für Code zur Fehlersuche, zur Synchronisation oder zur Persistenz. Hierbei handelt es sich um Programmbestandteile, die nicht unmittelbar fachliche Anforderungen darstellen, so genannte Aspekte. Aspektcode ist meist über das gesamte Programm verstreut und beeinträchtigt oft das Lesen und Verstehen der Quelle. Die aspektorientierte Programmierung, kurz AOP, (www.parc.xerox.com/aop und http://aspectj.org) stellt Mittel bereit, mit denen Aspektcode aus einem Programm herausgelöst und als eigenständiges Modul erstellt wird. Ein so genannter AspectWeaver fügt schließlich zur Übersetzungszeit oder zur Laufzeit den fachlichen Code und den Aspektcode wieder zusammen (siehe Abbildung). Die AOP bietet klare Vorteile: Sie erlaubt eine weiter gehende Aufteilung eines Programms in Module und verbessert damit dessen Wartbarkeit und Verständlichkeit. Da Aspekte und Programmcode nicht mehr fest miteinander verbunden sind, ist es verhältnismäßig einfach, neue Programmversionen mit unterschiedlichen Aspekten zu erstellen, etwa die Endversion einer Software ohne Debugging-Anweisungen, aber mit Code zur Synchronisierung. Dabei ist die AOP nicht nur ein Zusatz zur objektorientierten Programmierung, sondern kann allgemein in der prozeduralen und funktionalen Programmierung eingesetzt werden. Die historischen Wurzeln der AOP reichen zurück auf das 1976 von Edsger W. Dijkstra formulierte Prinzip der "Trennung von Belangen" (Separation of Concerns) und die Before- und After-Methoden im Common Lisp Object System (CLOS). Mit AOP eng verwandt sind Adaptive Programming, Composition Filters, Integrationsorientierte Programmierung und Subject-Oriented Programming. Eine Weiterentwicklung der AOP erfolgt auf der Grundlage der mehrdimensionalen Trennung von Belangen. Was die Methodik angeht, ist die AOP zwar den Kinderschuhen entwachsen, aber immer noch Forschungsthema. So wundert es auch nicht, dass abgesehen von "AspectJ" und "HyperJ" für Java die Werkzeugunterstützung ansonsten eher rar ist.

Anlehnung an Konzepte von Ada und C++

Die generische Programmierung (siehe zum Beispiel www.cs.rpi.edu/musser/gp) ist gewissermaßen der "Senior" unter den neuen Ansätzen. In erster Linie bezeichnet sie die Programmierung mit generischen Parametern, wie sie aus Ada und C++ bekannt sind. Auf diese Weise werden Datenstrukturen unabhängig vom Typ entwickelt. Erst bei der Verwendung einer Datenstruktur gibt der Entwickler an, ob beispielsweise ein Stapel für Ganzzahlen oder für Spielkarten benötigt wird. Die Standard Template Library für C++, kurz STL, zeigt, dass außer Typen auch Verhaltensweisen, beispielsweise ein Sortierkriterium oder die Art der Speicherbeschaffung, zu generischen Parametern werden können. Ein generischer Softwarebaustein fasst also die Gemeinsamkeiten seiner konkreten Ausprägungen zusammen und sieht generische Parameter für die Anteile vor, die unterschiedlich ausfallen können. Der große Erfolg der STL und die Tatsache, dass beispielsweise in der C++-Standardbibliothek die generische Programmierung die objektorientierten Techniken wie Vererbung und spätes Binden weit gehend verdrängt hat, sprechen für sich. Die generische Programmierung ruht auf einem stabilen theoretischen Fundament und ist Bestandteil vieler Programmiersprachen. Möglicherweise gibt es Templates demnächst sogar in Java. Ein Wermutstropfen ist jedoch, dass die generischen Konzepte in der Unified Modelling Language (UML) nur rudimentär unterstützt werden.

Die generative Programmierung dient nicht mehr nur der Entwicklung einzelner Systeme, sondern ganzer Familien von Softwaresystemen. Zu diesem Zweck wird ein so genanntes generatives Domänenmodell erstellt. Dieses umfasst den Problemraum mit einer oder mehreren domänenspezifischen Sprachen (englisch Domain Specific Langauge, Abk. DSL), den Lösungsraum mit elementaren, möglichst frei kombinierbaren und wiederverwendbaren Implementierungsbausteinen, sowie einen Generator, der die Beschreibung eines Zwischen- oder Endprodukts in DSL analysiert und eine optimierte und hochangepasste Konfiguration des gewünschten Produkts aus Implementierungsbausteinen erstellt.

Definition von Domänen für Softwarefamilien

Die Modellierung eines Anwendungsbereichs (Domäne) erfolgt mit Hilfe von Merkmalen. Dabei wird zwischen Merkmalen unterschieden, die in allen Systemen (Muss-Merkmale), und solchen Merkmalen, die nur in bestimmten Systemen vorhanden sind (Kann-Merkmale). Im Merkmal-Modell werden außerdem die Standardvorgaben für Merkmale sowie die Wechselwirkungen und Abhängigkeiten zwischen den Kann-Merkmalen dokumentiert. Aus dem Merkmalmodell leiten sich schließlich die Implementierungskomponenten, die DSL und das Konfigurationswissen des Generators ab. Die methodischen Ursprünge liegen im Domain-Engineering, insbesondere dem Feature-Oriented Domain Engineering (FODA), und dem Organization Domain Modeling (ODM).

Während die generische Programmierung den Schwerpunkt auf die Bildung von Familien von Implementierungskomponenten legt, ergänzt die generative Programmierung dies um die domänenspezifische Beschreibung von Komponenten und Systemen sowie deren Herstellungsprozess. Interessanterweise existieren historisch gesehen kaum Berührungspunkte mit den klassischen Anwendungsgeneratoren, die beispielsweise für Cobol verbreitet waren und immer noch im Einsatz sind, es besteht aber ein ausgeprägter Bezug zur Metaprogrammierung und zur aspektorientierten Programmierung. Die generative Programmierung kann auf verschiedene Implementierungstechniken abgebildet werden. Es liegen mehrere positive Erfahrungen mit C++ unter anderem im Bereich wissenschaftliches Rechnen (Matrix Template Library) und im industriellen Einsatz (generative Bibliothek für statische Algorithmen und Zähler in der Postautomatisierung) vor. Erste Erfahrungen gibt es darüber hinaus mit Java, wobei Entwicklungsumgebungen in der Art des Intentional Programming System die generative Programmierung künftig besser unterstützen können.

KOMMENTAR: Die (Wieder-)Entdeckung des Menschen

Wenn der Eindruck nicht trügt, dann kommt beim Thema Softwareentwicklung den "weichen" Faktoren, also den sozialen Aspekten immer, stärkere Aufmerksamkeit zu. Publikationen über den Sinn und Unsinn von strengen Planungen und detaillierten Pflichtenheften, über soziale Organisationsformen von Programmierteams oder die Interaktion von Projektverantwortlichen und Anwendern haben Konjunktur. Das kann daran liegen, dass sich die Debatten um Objektorientierung und Komponentensoftware aufgrund deren Erfolgs weitgehend totgelaufen haben.

Wenn also trotz hervorragender Werkzeuge und von Grund auf betriebener Objektorientierung viele Projekte scheitern, dann gerät nun zwangsläufig die Projektorganisation unter Verdacht. Neuere Untersuchungen sprechen von 40 Prozent Fehlschlägen, wenn mehr als 20 Mitarbeiter beteiligt sind. Natürlich gelten da teilweise immer noch die alten Erklärungen: Projektleiter, die ihr Geschäft nicht lernen müssen, weil sie glauben, dass ihnen alle notwendigen kommunikativen und organisatorischen Fähigkeiten in die Wiege gelegt wurden, ahnungslose Auftraggeber, die dem Treiben tatenlos zusehen, und natürlich die notorische Zeit- und Personalknappheit.

Nachdem diese Übel wohl nie ganz verschwinden werden, sollen modisch gewordene Ansätze wie eXtreme Programming, Projekte flexibler und überschaubarer machen. Der Tenor lautet: Reduktion des Planungsaufwands, Verkleinerung von Teams und frühe Auslieferung von lauffähigem Code. Unübersehbar sind dabei Ähnlichkeiten mit der Entwicklungsmethode von Open Source, besonders das Credo "release early, release often".

Trotz der neuen Aufmerksamkeit für die sozialen Faktoren der Softwareentwicklung steht der Fortschritt beim Engineering nicht still. Eine Reihe interessanter Ansätze wie die generative Programmierung oder Softwareproduktlinien versprechen grundlegende Umwälzungen. Bis sie die Forschungslabors verlassen haben und reif für die Praxis sind, wird indes noch einige Zeit vergehen. (Wolfgang Sommergut)

Das Intentional Programming System, kurz IP-System, von Microsoft verzichtet bei der Softwareentwicklung auf den Einsatz von Programmiersprachen im herkömmlichen Sinn. Stattdessen wird ein Programm als Quellgraph in einer Datenbank abgelegt. Damit fallen einige bekannte Probleme der textbasierten Programmierung wie etwa die Kollision von Bezeichnern oder die mühsame Suche der passenden Definition zu einem Bezeichner einfach weg. Der Quellgraph umfasst den abstrakten Syntaxbaum sowie Methoden beispielweise zur Eingabe, Bearbeitung, Darstellung oder Transformation der enthaltenen Abstraktionen. Zusammenhängende Sprachmerkmale, sogenannte Abstraktionen, werden in aktiven Bibliotheken gruppiert. Aktive Bibliotheken sind auch die Bausteine, mittels derer für bestimmte Aufgaben optimierte Entwicklungsumgebungen konfiguriert werden. Die Eingabe und Darstellung von Programmabstraktion orientiert sich dabei an der jeweiligen Anwendungsdomäne. Textuelle Darstellungen können mit domänenspezifischen grafischen Darstellungen beliebig gemischt werden. Diese Eigenschaften des IP-Systems bilden eine hervorragende Grundlage für die aspektorientierte und die generative Programmierung. Sogar komplette Programmiersprachen wie beispielsweise C++ können im Prinzip als aktive Bibliothek in das IP-System geladen werden. Damit kann vorhandener C++-Quellcode importiert und weiterverarbeitet werden. Spezielle Werkzeuge sollen den Entwickler dann beim Reengineering eines Altsystems unterstützen.

Intentional Programming bedeutet eine grundlegende Veränderung der Softwareentwicklung: Statt der Evolution der Programmiersprachen wird es eine Evolution der Abstraktionen geben. Wer heute bestimmte Sprachmerkmale und -eigenschaften einsetzt, muss die gesamte dazu gehörige Programmiersprache verwenden. Eines Tages wird man aus einem sprachunabhängigen Angebot die am besten geeigneten Abstraktionen auswählen können, sie parametrisieren und gegebenenfalls den Code für ihre gemeinsame Verwendung schreiben. Obwohl Microsoft das IP-System vor kurzem in den Produktentwicklungsstatus erhoben hat, wird es aber voraussichtlich noch eine ganze Weile dauern, bis es das Licht der Öffentlichkeit erblickt.

Gegenwärtig werden überwiegend einzelne Systeme entwickelt. Doch wie soll aus der Entwicklung von Einzelstücken etwas Wiederverwendbares hervorgehen? Rahmenwerke, Entwurfsmuster und Komponenten bringen zwar Besserung, aber keinen Durchbruch. Einen deutlichen Fortschritt verspricht die Entwicklung von Softwareproduktlinien, auch Softwaresystemfamilien genannt. Ihre Grundlage ist das Domain-Engineering, wobei ein besonderer Schwerpunkt auf der Anwendungsentwicklung liegt.

Einfache Erzeugung von Systemvarianten

Eine Softwareproduktlinie erlaubt die anforderungsspezifische Fertigung einer großen Zahl von Systemvarianten, die weit gehend automatisiert werden kann. Dies ist wiederum ein Ziel der generativen Programmierung, welche die maximale Automatisierung der Variantenherstellung anstrebt. Gegenüber der herkömmlichen objektorientierten oder komponentenbasierten Softwareentwicklung besitzt der Produktlinienansatz mehrere Vorteile: Geeignete Implementierungskomponenten werden nur einmal entwickelt und anschließend im Rahmen eines Produktionsplans verwaltet. Da sie exakt aufeinander abgestimmt sind, entfallen idealerweise manuelle Anpassungsaufwand und Glue-Code. Solange die Anforderungen an ein System nicht über die Systemfamilie hinausreichen, sind auch keine Einschränkungen und Kompromisse hinsichtlich der Systemfunktionalität nötig. Änderungen und Erweiterungen der Anforderungen bedingen einen neuen Durchlauf des Domain Engineering. Erforderliche Änderungen können dann gezielt vorgenommen werden, wobei die Auswirkungen einer Änderung besser absehbar sind, als dies bisher der Fall ist. Die Entwicklung einer Softwareproduktlinie ist unter verschiedenen Voraussetzungen sinnvoll, zum Beispiel bi der Herstellung von Systemen mit länderspezifischen oder kundenspezifischen Varianten, Software für eingebettete Systeme (sofern diese ebenfalls in Varianten auftreten), wechselnden Anforderungen hinsichtlich Ressourcenverbrauch, Genauigkeit, Durchsatz von Verarbeitungen sowie Systemplattform und -umgebung. Die Akzeptanz der Entwicklung von Softwaresystemfamilien ist auf dem Vormarsch und inzwischen liegen ausreichend Erfolgsgeschichten und Erfahrungsberichte vor (siehe dazu Donohoe, Software Product Lines).

eXtreme Programming (www.xprogramming.com und www.extremeprogramming.org), kurz XP, fällt gegenüber den anderen Themen ein wenig aus der Reihe. Einer der geistigen Väter von XP, Kent Beck, machte in seiner Praxis als Entwickler und Berater die Erfahrung, dass der Weg zum lauffähigen Code zu oft mit Hindernissen gepflastert ist, etwa ein Übermaß an Bürokratisierung der Softwareentwicklung, unverständliche und ungenutzte Dokumentationen, mangelnde Entscheidungskompetenz seitens der Ansprechpartner beim Kunden oder überhaupt keine Ansprechpartner, unklare Spezifikationen, schlechte Codequalität, übermäßig lange Arbeitszeiten der Programmierer und so weiter. Konsequenterweise arbeitete Kent Beck an einer Neuausrichtung und Verschlankung des Entwicklungsprozesses mit dem Ziel, qualitativ hochwertigen Code in kurzer Zeit kostengünstig zu erstellen. Heraus kamen dabei die berühmten zwölf Richtlinien von XP, unter anderem die Forderung nach einer 40-Stunden-Woche, Regressionstests, Standards und Konventionen zur Code-Erstellung, Verwendung geeigneter Metaphern bei der Namensgebung und das Programmieren in Zweierteams. Die Urheber von XP betonen ausdrücklich, dass der Einsatzbereich von XP auf eher kleine Projekte und Zweierteams beschränkt ist. Sind diese Voraussetzungen erfüllt, kann der Einsatz von XP erwogen werden und ist auch durchaus in Verbindung mit aspektorientierter Programmierung oder einem anderen der vorgestellten Ansätze möglich. Nicht zuletzt aufgrund der Tatsache, dass XP der Praxis entstammt, hat es eine gewisse Reife erlangt, und es existiert eine hinreichende Zahl von Erfolgs- und Erfahrungsberichten. Seltsam ist nur, dass oftmals hitzige Diskussionen pro oder contra XP geführt werden. Wer als Entwickler und Berater in wechselnden Unternehmen für eher kurze Zeiträume in Softwareentwicklungsprojekte eingebunden ist, sollte einfach nüchtern prüfen, ob XP für ihn geeignet ist.

Fazit

Hinter den Schlagwörtern steht keineswegs nur heiße Luft! Mehrere Ansätze sind so weit ausgereift, dass sie nach Prüfung ihrer Voraussetzungen risikolos und Erfolg versprechend eingesetzt werden können. Dazu gehören die generische Programmierung und XP. Die größten Auswirkungen auf das Software-Engineering wird mittel- und langfristig die Entwicklung von Softwaresystemfamilien haben. Generische Programmierung und aspektorientierte Programmierung sind aussichtsreiche Techniken, die hierbei hilfreich sind. Für die generative Programmierung gilt als Spezialisierung des Produktlinienansatzes in dafür geeigneten Anwendungsbereichen der gleiche Zeithorizont. Während generische und aspektorientierte Programmierung eher von der Verfügbarkeit geeigneter Programmierwerkzeuge abhängig sind, können die Entwicklung von Softwaresystemfamilien und die generative Programmierung als Methoden und Vorgehensweisen auf unterschiedliche Implementierungstechniken abgebildet werden. Die Zukunft des IP-Systems steht noch mehr in den Sternen, die Beschäftigung mit seinen Konzepten kann aber wertvolle Anregungen für neue Entwicklungstechniken und -umgebungen liefern.

LITERATUR

Krzysztof Czarnecki, Ulrich W. Eisenecker: Generative Programming. Methods, Tools, and Applications. Addison-Wesley 2000

Patrick Donohoe (Hg): Software Product Lines: Experience and Research Directions, Proceedings of The First Software Product Line Conference (SPLC1), August 28-31, 2000, Denver, Colorado. Kluwer International Series in Engineering and Computer Science, Boston, 2000

Ulrich W. Eisenecker, Lutz Röder, Krzysztof Czarnecki: Freiheit für Entwickler. Intentional Programming: Programmierung ohne Sprache. In: iX 11/2000, S. 142-147

Ulrich W. Eisenecker, Krzysztof Czarnecki: Management von Softwaresystemfamilien. In: OBJEKTspektrum 2/2001

Dr. Ulrich W. Eisenecker ist Professor für Informatik an der Fachhochschule Kaiserslautern, Standort Zweibrücken, und Koautor des Buches "Generative Programming. Methods, Tools, and Applications".