Universität-Gesamthochschule
Siegen
| Uni-GH Siegen | FB Elektrotechnik und Informatik | UniPlaner |
Auch an der Universität Utrecht hat eine Forschungsgruppe begonnen sich mit den Möglichkeiten der Werkzeugunterstützung für Entwurfsmuster zu beschäftigen. Scheinbar hat man sich, genau wie bei IBM, schwer getan, einen klangvollen Namen für den dort entwickelten Prototypen zu finden. So ist im folgenden die Rede vom Utrecht-Prototypen.
Während sich der IBM-Prototyp auf die Entwurfsmuster-Ebene konzentriert, sich also primär mit der Generierung von Source-Code aus Entwurfsmustern beschäftigt, geht der Ansatz der Universität Utrecht weiter. Die Entwickler wollten sich nicht auf die Entwurfsmuster-Ebene beschränken, da sie der Meinung sind, daß ein Programm nicht alleine aus Entwurfsmustern erstellt werden kann der Benutzer muß vielmehr an der Architektur arbeiten und Methoden programmieren können, um eine Anwendung zu erstellen.
Der Prototyp besteht deshalb aus verschiedenen Werkzeugen, die jeweils unterschiedliche Sichten auf das gemeinsame Datenmodell anbieten. Je nachdem welche Sicht man wählt, erhält man verschiedene Manipulationsmöglichkeiten für das Datenmodell. Die Abstraktionsebenen, die angeboten werden, sind die Entwurfsmuster-Ebene, die Design-Ebene und die Code-Ebene. Der Benutzer kann beliebig zwischen den Ebenen wechseln, ohne den Verlust von Informationen befürchten zu müssen.
Auf der Entwurfsmuster-Ebene werden die dem Programm bekannten Entwurfsmuster und die Instanzen dieser Muster präsentiert. Die Design-Ebene enthält die Klassenhierarchie des Projekts, während die Code-Ebene Einblick in die Implementierung der Methoden gewährt. Nähere Informationen zu den verwendeten Werkzeugen und der Architektur des Prototypen folgen gleich.
Von der Konzeption her ist der Prototyp sowohl für die Entwicklung von Software als auch für das Re-Engineering von Projekten gedacht, da es möglich ist, bestehende Programme in das Werkzeug "einzuladen" und neu zu organisieren. Man kann nachträglich das Design verändern, um Entwurfsmuster in ein bestehendes Programm einzubringen. So geschehen am Beispiel eines in Smalltalk geschriebenen WWW-Browsers, der aus über 150 Klassen besteht und in dem die Anwesenheit von einigen GoF-Entwurfsmustern dokumentiert werden konnte.
Gegenwärtig wird von dem Prototypen die Sprache Smalltalk unterstützt, was sich allerdings mit einigem Aufwand auch ändern läßt. In Zukunft möchten die Entwickler möglichst weitgehend sprachunabhängig arbeiten, aber derzeit sind die Muster noch durch Design-Elemente definiert, für die eine direkte Transformation in den Source-Code der verwendeten Sprache vorgegeben ist. Das ist nicht sehr flexibel, löst aber das Problem, daß in vielen Sprachen bestimmte Design-Elemente mehrere Repräsentationen unter den Sprach-Elementen haben. Es wird eben eine Transformation festgelegt.
Für die eigentliche Arbeit mit Entwurfsmustern haben die Entwickler prinzipiell drei Möglichkeiten vorgesehen:
Da außer der Arbeit mit Entwurfsmustern aber auch das Editieren auf Design- und Code-Ebene gestattet sein sollte, mußten die Entwickler einige Dinge beachten: Eine Änderung, die auf der Design- oder Code-Ebene durchgeführt wird, kann zunächst einmal bedeuten, daß das Muster immer noch richtig verwendet wird, da es möglicherweise viele verschiedene korrekte Implementierungen zu diesem Muster gibt. Es ist aber auch möglich, daß ein vorher eingebrachtes Muster nach den Änderungen nicht mehr korrekt wiedergegeben wird. Das Werkzeug muß den Entwickler unbedingt in dieser Sache unterstützen und ihm verschiedene Reaktionsmöglichkeiten anbieten.
So bietet der Utrecht-Prototyp dem Benutzer unter anderem an, das "Verletzen" eines Musters zu ignorieren oder den Schaden vom Werkzeug automatisch beheben zu lassen. Ein wichtiger Mechanismus, der für diese Unterstützung benötigt wird, ist eben das "Binden" von Elementen des Programms an die Elemente eines Musters, so daß das Werkzeug bei der Änderung eines solchen Elementes auf der Design- oder Code-Ebene prüfen kann, ob das Muster noch korrekt wiedergegeben wird. Dafür werden spezielle Konsistenz-Constraints benötigt, die aussagen, wann die Konsistenz bestimmter Bindungen eingehalten wird und wann sie verletzt wird. Zu den Details über diese Prüfung und die anschließende Fehlerbehandlung sei auf [4] verwiesen. Neben den beiden angesprochenen Reaktionsmöglichkeiten existieren noch weitere "Abstufungen". Wichtig ist auch die eingebaute Undo-Möglichkeit, welche die letzte bzw. die letzten Aktionen des Benutzers rückgängig macht.
Während die Entwickler bei IBM für die Darstellung von Entwurfsmustern auf HTML zurückgreifen konnten, war dies hier nicht möglich. Für die Verwirklichung der oben genannten Funktionen (z. B. Konsistenzprüfung) mußte eine spezielle interne Muster-Repräsentation gewählt werden. Textuelle Beschreibungen sind dazu wenig hilfreich und wurden einfach weggelassen. Allgemeine OO-Strukturen (z. B. Klassen, Vererbung, Methoden, Attribute) sind nur eingeschränkt für eine solche Beschreibung geeignet, da mit ihnen beispielsweise keine Persistenz oder Nebenläufigkeit ausgedrückt werden kann. Die Entwickler suchten nach einem speziellen Modell, das in dieser Hinsicht keine Beschränkungen aufweist. So sollte es auch das Schaffen von neuen Design-Elementen zu einem späteren Zeitpunkt gestatten, wenn die bereits vorhandenen Elemente für die Beschreibung nicht mehr ausreichen sollten.
Aufgrund dieser Überlegungen entstand das Fragment Model, das Grundlage der Fragment Database des Werkzeugs ist. Hier werden die Informationen über einsetzbare Entwurfsmuster und die Daten eines Projektes gehalten. Ein Fragment ist nun ein einzelnes Design-Element, das eine Typ-Information trägt. Eine solche Typ-Information kann z. B. Klasse, Methode, Muster, Assoziation oder etwas ähnliches sein. Außerdem besitzen Fragmente sogenannte Rollen, die Verweise auf andere Fragmente enthalten können. Einige spezielle Fragmente können auch Source-Code enthalten oder mit einer Verhaltensweise ausgestattet sein, wie z. B. das Prüfen von Konsistenz-Constraints.
Ein Programm kann somit als Graph von miteinander verknüpften Fragmenten unterschiedlichen Typs dargestellt werden. Um dieses zugrundeliegende Datenmodell noch etwas näher zu erläutern, folgt nun ein Beispiel, das im wesentlichen [4] entnommen wurde.
Die Abbildung 3-1 zeigt das recht bekannte Entwurfsmuster Observer (deutsch: Beobachter) aus dem GoF-Buch (siehe [2]) und eine Instanz des Musters in der OMT-Notation. Observer ist ein objektbasiertes Verhaltensmuster, welches das aus Smalltalk bekannte Model-View-Controller-Konzept in ein Muster umsetzt. Prinzipiell wird hier die Daten-Darstellung von den zugrundeliegenden Anwendungsdaten getrennt. So ist es möglich, daß mehrere Beobachter (z. B. mehrere Fenster einer Windows-Anwendung) die Anwendungsdaten auf unterschiedliche Art und Weise präsentieren und die Modifizierung der Daten erlauben. Werden über einen Beobachter (Ausprägungen der Klassen ObserverA, ObserverB) die Daten geändert, so werden alle anderen Beobachter von dem die Daten haltenden Objekt (eine Ausprägung der Klasse ConcrSubject) informiert und können ihre Darstellung aktualisieren.

Abbildung 3-1: Das Muster Observer
Eine Darstellung des Diagramms aus Abbildung 3-1 ergibt bereits einen sehr aufwendigen Graphen, so daß aus Gründen der Übersicht nur die numerierten Elemente in den Graphen der Abbildung 3-2 übernommen wurden. Der Graph hat als "Wurzel" das Fragment MyObserver, das alle Fragmente zusammenhält. Schaut man sich das Fragment ObserverA (mit 4 beziffert) an, stellt man fest, daß dieses Fragment sowohl über die Rolle method verfügt, die es mit dem Fragment Update (5) verknüpft, als auch Bestandteil der Rolle sub ist, die zum Fragment ObserverHier (3) gehört. Ein Fragment kann also selbst Rollen besitzen und gleichzeitig auch Bestandteil einer Rolle sein.

Abbildung 3-2: Das Muster Observer im Fragment Model
Interessant ist, wie auch die Vererbungsbeziehung (3) im Klassendiagramm eine Repräsentation als Fragment findet. Das Fragment ObserverHier erfüllt diese Aufgabe, indem es Rollen für die Elternklasse (2) und die beiden Tochterklassen (4, 6) enthält, welche auf die entsprechenden Klassen verweisen. Das oben angesprochene Fragment Update (5) ist von einem speziellen Typ, der keine eigenen Rollen enthält, aber dafür Source-Code aufnehmen kann. Hier wird der Code der Methode Update() gespeichert, wenn sie später einmal implementiert wird.
Man kann sich leicht vorstellen, daß der Graph bei einem realen Projekt sehr groß wird. Dieses "einfache" Beispiel vermittelt hoffentlich ein Grundverständnis für das Konzept des Fragment Models. Für tiefergehende Informationen sei wieder auf [4] verwiesen, da das Konzept dort sehr ausführlich beschrieben wird.
Auf diesem Datenmodell arbeiten nun die Werkzeuge Fragment Browser, Fragment Inspector, OMT Tool und Code Tool. Diese Werkzeuge ermöglichen das Arbeiten auf den Ebenen Entwurfsmuster, Design und Code.
Eine zentrale Rolle spielt OMT Tool, das ein High-Level-Werkzeug für die Arbeit auf der Design-Ebene darstellt. Es stellt Design-Elemente in der bekannten OMT-Notation dar und erlaubt die Modifikation dieser Elemente sowie das Erstellen neuer Elemente wie Klassen, Methoden etc. Das Werkzeug wurde auf der Basis des Smalltalk Refactoring Browsers entwickelt, der an der Universität Illinois erstellt wurde. Aus ihm lassen sich auch die anderen Werkzeuge aufrufen. So kann mit Hilfe des Code Tools der Source-Code zu einer Methode erstellt und dann in das Modell übernommen werden.
Die beiden übrigen Werkzeuge wurden bereitgestellt, um auf der Entwurfsmuster-Ebene zu arbeiten. Mit Hilfe des Fragment Browsers läßt sich der Graph eines Projektes anzeigen und Fragmente lassen sich beispielsweise löschen oder erzeugen. Der Fragment Inspector kann aus dem Fragment Browser aufgerufen werden, um Informationen über ein einzelnes Fragment zu erhalten und diese zu modifizieren. Dabei sind die Darstellungsmöglichkeiten und der Benutzungskomfort dieser beiden Werkzeuge stark begrenzt.
Soviel zunächst zur Vorstellung des Utrecht-Prototypen. Vor- und Nachteile werden abschließend im Kapitel 4 gegenübergestellt.
[Titel][Vorwort][Inhalt][Kapitel 1][Kapitel 2][Kapitel 3][Kapitel 4][Literatur]
© Wintersemester 97/98 by Sascha Meyer