
Die aspektorientierten Technologien AspectJ und Hyper/J sind die am weitesten verbreiteten Sprachen für aspektorientierte Programmierung, wobei AspectJ bereits in ersten industriellen Projekten eingesetzt wird.
Dagegen sind die Programmiermodelle ObjectTeams und Caesar Neuentwicklungen der TU Berlin und der TU Darmstadt, die in Zusammenarbeit der jeweiligen Arbeitsgruppen entstanden sind und verschiedene Verbesserungen gegenüber den beiden etablierten aspektorientierten Ansätzen und der konventionellen Objektorientierung in einem einheitlichen Modell vereinen. Alle verwendeten neuen Konzepte dienen dem Ziel, die Modularität komplexer Software zu verbessern, um damit Verständlichkeit, Wartbarkeit und Erweiterbarkeit der Software zu steigern.
Ansätze für den kollaborationsbasierten Entwurf führen Kollaborationen als Module ein, die das Zusammenspiel verschiedener Klassen ("Rollen") kapseln. Dies basiert u.a. auf der Beobachtung, dass Klassen als Module in großen Systemen zur Strukturierung nicht ausreichen. Die neuen Programmiermodelle erlauben dabei erstmals eine direkte Umsetzung des kollaborationsbasierten Entwurfes im Sinne von z.B. Catalysis, der mit rein objektorientierten Sprachen nicht zufriedenstellend implementiert werden kann.
Subject-oriented programming gehört zu den ersten Ansätzen, die spezielle sprachliche Unterstützung für die Integration von Modulen bereitstellen. Dies ist von zentraler Bedeutung, um die Unabhängigkeit von Modulen zu fördern: nur wo Adaptierung von Schnittstellen systematisch unterstützt wird, können unabhängig voneinander entwickelte Module gemeinsam eingesetzt werden, bzw. integrierte Module nach unterschiedlichen Anforderungen weiterentwickelt werden.
Architekturbeschreibungssprachen sowie Komponententechniken wie CCM (Corba Component Model) führen die konzeptionelle Unterscheidung von expected und provided interfaces ein. Neue Arbeiten übertragen diese Unterscheidung in die Ebene von Programmiersprachen. Der Effekt ist, dass auch ein client-Modul Anforderungen an seinen Benutzungskontext stellen kann.
Die Sprachen beta bzw. gbeta führen das Konzept der virtual classes ein, das es erlaubt, eine Gruppe von sich gegenseitig referenzierenden Klassen in einem Schritt zu spezialisieren unter Vermeidung der Typprobleme, die andere Programmiersprachen in dieser Situation aufweisen (Kovarianz). Dadurch wird Vererbung von der Klassenebene auf die Kollaborationsebene übertragen.
Prototypbasierte Sprachen wie Self bieten die Möglichkeit, eine Vererbungsbeziehung zwischen Objekten zu definieren, was in vielen Veröffentlichungen auch als Rollenobjekte bezeichnet wird. Während Self eine klassenlose Programmiersprache ist, kombinieren neuere Ansätze wie Lava die Klassenvererbung mit dem Konzept von Rollen mit Delegation. Die lose Kopplung, die hierdurch erreicht wird, bietet eine Flexibilität, die bei konventionellen Techniken nur mit erheblichem Mehraufwand möglich ist.
Aspektorientierte Sprachen wie AspectJ führen das Konzept des Aspekt-Webens (engl. weaving) ein, wodurch zusätzlicher Code in bestehende Klassen eingefügt werden kann. Diese Adaptierung geschieht im Fall von AspectJ bei der Kompilation, so dass der Quelltext dieser Klassen nicht verändert werden muß.
Dynamische Aspektsprachen wie AspectS erlauben das dynamische Aktivieren und Deaktivieren von Aspekten zur Laufzeit. Wenn Aspekte darüber hinaus instanziierbar sind, kann dieselbe Aspektdefinition auch mehrfach gleichzeitig aktiviert werden. Dies trägt der Beobachtung Rechnung, dass sich Software in verschiedenen Situationen unterschiedlich verhalten soll. Das explizite Ausprogrammieren von Bedingungen und Alternativen durchzieht in konventionell entwickelten Programmen die gesamte Struktur, wodurch mehrere Entwurfsprinzipien verletzt werden. Programme mit derartiger Struktur sind weder verständlich, noch mit angemessenem Aufwand wartbar. Aspektaktivierung konzentriert Fallunterscheidungen an sehr wenige Stellen im Programm und überläßt den Rest dem Laufzeitsystem (analog dem dynamischen Binden von Methoden).
Die gerade beschriebenen Ansätze werden in unterschiedlichem Grad in beiden von TU-Darmstadt und TU-Berlin entwickelten Programmiermodellen, ObjectTeams und Caesar, realisiert.
Beiden Programmiermodellen ist gemein, dass es neue Modulkonstrukte für Mengen kollaborierender Klassen gibt. Diese Modulkonstrukte haben ähnliche Eigenschaften wie Klassen (Instanziierung, Vererbung, Polymorphie). Anders als eine Klasse, die das Verhalten einer Menge definiert, beschreiben diese Module jedoch Mengen zusammenarbeitender Abstraktionen. A-posteriori-Integration dieser Module wird durch spezielle Bindungs- oder Konnektorkonstrukte realisiert, die dazu dienen, die Funktionalität des Moduls nicht-invasiv in neue Kontexte einzuflechten. Ferner stellen beide Programmiermodelle Konstrukte bereit, mit denen die Aktivierung gebundener Kollaborationesmodule zur Laufzeit geschehen kann.
Unterschiede zwischen den Programmiermodellen gibt es sowohl auf konzeptioneller Ebene als auch in der Implementierung. Durch sog. collaboration interfaces werden in Caesar die Bindungen von Kollaborationsmodulen von der konkreten Implementierung eines solchen Moduls getrennt, wodurch es möglich wird, Bindungen mit verschiedenen Implementierungen wiederzuverwenden. Weitere Unterschiede sind in der Art, wie ein Kollaborationsmodul an einen neuen Kontext gebunden wird. In ObjectTeams wird hierzu eine eigene deklarative Subsprache verwendet, während in Caesar die Verbindung im Wesentlichen in "pure Java" realisiert wird.
Auf der Implementierungsebene liegt ein Unterschied darin, dass in ObjectTeams konventionelle Kompilation mit weaving zur Ladezeit verknüpft wird, während Caesar einen konventionellen Compiler mit dem bytecode weaver der Sprache AspectJ verknüpft. Beide Techniken erlauben es, Klassen und Pakete zu adaptieren, deren Quelltext nicht verfügbar ist. Das load-time-weaving der ObjectTeams-Implementierung erleichtert ferner das Konfigurationsmanagement, dadurch, dass keine verschiedenen Varianten (mit und ohne Aspekte) derselben Klassen gespeichert werden müssen, da diese erst beim Programmstart erzeugt werden.
| weiter: 3 Fallstudie |