Automatisches Layout von UML-Klassendiagrammen

Größe: px
Ab Seite anzeigen:

Download "Automatisches Layout von UML-Klassendiagrammen"

Transkript

1 Diplomarbeit Automatisches Layout von UML-Klassendiagrammen vorgelegt von Martin Siebenhaller Juni 2003 Betreuer: Prof. Dr. M. Kaufmann Arbeitsbereich Paralleles Rechnen Wilhelm-Schickard-Institut für Informatik Fakultät für Informations- und Kognitionswissenschaften Eberhard-Karls-Universität Tübingen

2 ii

3 Inhaltsverzeichnis 1 Einführung Motivation Überblick Grundlagen Graphen Planarität Orthogonale Zeichnungen von planaren Graphen Min-Cost-Flow Notation von UML-Klassendiagrammen Klassen Beziehungen Vererbung (inheritance) Assoziation (association) Abhängigkeit (dependency) Pakete (packages) Erweiterungsmechanismen Zusicherungen (constraints) Eigenschaften (properties) Stereotypen (stereotypes) Notizen (notes) Konsequenzen für den Layoutalgorithmus Ästhetikkriterien Syntaktische Ästhetikkriterien Semantische Ästhetikkriterien Auswahl geeigneter Ästhetikkriterien Der Topology-Shape-Metrics Ansatz Definition Einbettung GT-Heuristik Routen von Kanten

4 iv INHALTSVERZEICHNIS Rerouting von Kanten Orthogonalisierung Tamassias Algorithmus Das Kandinsky-Modell Kompaktierung Ein Layoutalgorithmus für UML-Klassendiagramme Hyperkanten und Vererbungsgabeln Der Basisalgorithmus Formzuweisung für die aufwärtsgerichteten Kanten Knickreduzierung Umsetzung der vorgegebenen Form durch das Kandinsky- Netzwerk Einheitliche Ausrichtung der aufwärtsgerichteten Kanten Verbesserungen des Basisalgorithmus Einbettung Höhenkanten Behandlung von Selbstschleifen Der gesamte Algorithmus Überblick Laufzeit Implementierung Design des Layoutalgorithmus Anwendung des Layoutalgorithmus Zusammenfassung und Bewertung 93 A Beispieldiagramme 99

5 Abbildungsverzeichnis 1.1 Ein kleines UML-Klassendiagramm Planare Repräsentation eines Graphen Planarer Graph, der nicht Aufwärtsplanar ist Orthogonale Gittereinbettung eines Graphen Orthogonale Repräsentation eines Graphen Zusammenhang der Zeichenketten Darstellung einer Klasse in UML-Klassendiagrammen Darstellung von Beziehungen in UML-Klassendiagrammen Darstellung von Paketen in UML-Klassendiagrammen Darstellung einer Notiz in UML-Klassendiagrammen Semantische Ästhetikkriterien Ersetzung einer Kantenkreuzung durch einen Knoten Darstellung der GT-Heuristik Darstellung eines st-graphen und dessen Routinggraph Darstellung eines Graphen und dem dazugehörigen dualen Graph Konstruktion des orthogonalen Netzwerks Beispiel leerer Faces Verbotene Flüsse im Kandinsky-Modell Das Kandinsky-Netzwerk Ersetzung eines Knotens durch viele kleine Knoten Ersetzung von Hyperkanten Mögliche Erweiterungen des Hyperkantenkonzepts Vom Algorithmus zugewiesene Formen Beispiel zur Knickreduzierung Unregelmäßige Vereinfachungen Entfernen von Knicken bei Kreuzungsknoten Weitere Transformationen bei Kreuzungsknoten Änderungen am Kandinsky-Netzwerks

6 vi ABBILDUNGSVERZEICHNIS 6.9 Behandlung von ungerichteten Kanten bei der Abbildung auf das Netzwerk Bestimmung der zu richtenden Kanten Zwei Kanten die sich bezüglich der Knotenfolge überschneiden Erzeugen von Höhenkanten zwischen Geschwisterknoten Verschiedene Fälle, die beim Einfügen von Höhenkanten auftreten Zwei alternative Platzierungen einer Selbstschleife Aufteilung der Kanten auf die Ports und mögliche Anordnung der Selbstschleifen Grafische Oberfläche des Jar-Inspectors UML-Klassendiagramm der verwendeten Klassen Bedienung des Jar-Inspectors Nicht ausgerichtete Vererbungsgabeln Schwächen der Einbettung Entstandene Schneckenform A.1 Beispieldiagramm A.2 Beispieldiagramm A.3 Beispieldiagramm A.4 Beispieldiagramm A.5 Beispieldiagramm A.6 Beispieldiagramm

7 Tabellenverzeichnis 3.1 Vordefinierte Zusicherungen der UML Vordefinierte Eigenschaften der UML Vordefinierte Stereotypen der UML Ästhetikpräferenzen für Klassendiagramme Vereinfachung der Form von Kanten

8 viii TABELLENVERZEICHNIS

9 Kapitel 1 Einführung 1.1 Motivation In der Softwareentwicklung hat sich seit Anfang der 90er Jahre immer mehr das objektorientierte Paradigma durchgesetzt. Der Trend zur Objektorientierung wird durch die große Beliebtheit objektorientierter Programmiersprachen wie C++ und Java unterstützt. Bei der objektorientierten Modellierung werden Objekte der realen Welt wie Personen, Dinge oder Gegenstände auf Objekte eines Softwaresystems abgebildet. Die Abbildung erfolgt durch geeignete Abstraktion, d.h. es werden nur relevante Eigenschaften der realen Objekte modelliert. Ein Objekt besitzt einen bestimmten Zustand und ein bestimmtes Verhalten. Im Objektmodell existiert also keine Trennung zwischen Daten und Funktionalität. Die objektorientierte Softwareentwicklung zeichnet sich besonders durch hohe Flexibilität, Erweiterbarkeit und Wiederverwendbarkeit aus. Sie erlaubt auch für komplexe Systeme eine sehr natürliche Beschreibung. Ein weiterer Vorteil zu bisherigen Verfahren ist, dass die Objektorientierung ein durchgängiges Konzept durch die Phasen Analyse, Entwurf und Implementierung bietet und somit den Entwicklungsprozess vereinfacht und die semantischen Lücken zwischen diesen Phasen schließt. Zu Beginn der 90er Jahre entstanden viele unterschiedliche Methoden zur objektorientierten Modellierung mit unterschiedlichen Notationen [19]. Es fehlte ein einheitlicher Standard. Deswegen entwickelten Booch, Rumbaugh und Jacobson (die drei Amigos ) ihre unterschiedlichen Modellierungsansätze zur Unified Modelling Language (UML) weiter. Es handelt sich bei der UML lediglich um eine grafische Notation, nicht um eine Methode, die den Entwicklungsprozess der Software vorgibt. Die UML bietet verschiedene Diagrammtypen mit unterschiedlichem Abstraktionsgrad zur Beschreibung eines Informationssystems an. Im November 1997 erklärte die Object Management Group (OMG) UML 1.1 zum OMG-Standard für die objektorientierte Modellierung. Durch die hohe Akzeptanz in der Industrie hat sich die

10 2 KAPITEL 1. EINFÜHRUNG UML inzwischen als Standardmodellierungssprache für die objektorientierte Softwareentwicklung etabliert und andere Ansätze nahezu verdrängt. Klassendiagramme sind ein Diagrammtyp der UML und dienen der Modellierung der statischen Struktur eines Systems [1]. Eine Klasse ist eine Art Schablone für gleichartige Objekte. Die Objekte einer Klasse werden auch als deren Instanzen oder Ausprägungen bezeichnet. Die Klasse legt Struktur und Verhalten der Objekte sowie deren Beziehungen zu anderen Objekten fest. Eine Klasse wird deshalb auch als abstrakter Datentyp bezeichnet. Klassendiagramme stellen Klassen und deren statische Beziehung untereinander dar. Oft beinhaltet die Darstellung einer Klasse auch deren Attribut- und Methodennamen (vgl. Abb. 1.1). In der Softwareentwicklung sind Klassendiagramme der wohl am häufigsten eingesetzte Diagrammtyp. MidiMessage data:byte[] length:int <init> + setmessage + getmessage + getstatus + getlength + clone +message MidiEvent + message:javax.sound.midi.midimessage + tick:long <init> + getmessage settick + gettick ShortMessage # MIDI_TIME_CODE:int # SONG_POSITION_POINTER:int # SONG_SELECT:int # TUNE_REQUEST:int # END_OF_EXCLUSIVE:int # TIMING_CLOCK:int # START:int # CONTINUE:int # STOP:int # ACTIVE_SENSING:int # SYSTEM_RESET:int # NOTE_OFF:int # NOTE_ON:int # POLY_PRESSURE:int # CONTROL_CHANGE:int # PROGRAM_CHANGE:int # CHANNEL_PRESSURE:int # PITCH_BEND:int <init> <init> + setmessage + setmessage + setmessage + getchannel + getcommand + getdata1 + getdata2 clone + getdatalength SysexMessage # SYSTEM_EXCLUSIVE:int # SPECIAL_SYSTEM_EXCLUSIVE:int <init> <init> + setmessage + setmessage + getdata + clone MetaMessage # META:int + defaultmessage:byte[] + datalength:int <init> <init> + setmessage + gettype + getdata + clone writevarint + <clinit> Abbildung 1.1: Ein kleines UML-Klassendiagramm. Die Zahl von Werkzeugen zur Softwareentwicklung, sogenannte CASE- Werkzeuge (Computer Aided Software Engineering), steigt ständig. Eine Hauptaufgabe dieser Werkzeuge ist es, aus Daten automatisch Diagramme zu generieren, um den Entwickler im Entwicklungsprozess zu unterstützen. Ein typisches Beispiel dafür ist die Erzeugung von Klassendiagrammen aus bereits bestehendem Programmcode, was unter den Begriff Reverse- Engineering fällt. Der Wissenschaftbereich automatisches Graphenzeichnen befasst sich mit der Entwicklung von Algorithmen zur Informationsvisualisierung. Dabei werden die Elemente von Graphen so geometrisch angeordnet, dass eine mög-

11 1.1. MOTIVATION 3 lichst schöne und verständliche Zeichnung entsteht. Ein Graph ist ein Konstrukt der diskreten Mathematik, das aus einer Menge von Knoten und einer Menge von Kanten besteht [4]. Eine Kante verbindet jeweils zwei (nicht notwendigerweise verschiedene) Knoten miteinander. Graphen werden verwendet, um Beziehungen zwischen Objekten zu beschreiben, wobei die Objekte durch Knoten und die Beziehungen durch Kanten repräsentiert werden. Beim automatischen Graphenzeichnen geht es also darum, Objekte und deren Beziehungen möglichst verständlich darzustellen. Automatisch bedeutet dabei, dass der Benutzer nicht in den Layoutprozess eingreifen muss. Die Positionierung der Knoten und Kanten wird allein vom Layoutalgorithmus bestimmt. Dies ermöglicht eine schnelle und einfache grafische Darstellung von großen Graphen, die manuell nur mit hohem Aufwand schön dargestellt werden können. Die Positionierung der Elemente und somit die Nützlichkeit der Zeichnung wird durch Ästhetikkriterien wie z.b. die Minimierung der Anzahl der Kantenkreuzungen beeinflusst. Die Wahl der verwendeten Ästhetikkriterien sowie deren Priorität hängt vom jeweiligen Anwendungsgebiet ab. Da der Layoutalgorithmus für die Realisierung der Ästhetikkriterien verantwortlich ist, besitzen unterschiedliche Anwendungsgebiete auch meist unterschiedliche bzw. modifizierte Layoutalgorithmen. Viele Probleme, die beim automatischen Graphenzeichnen auftreten, wie das Finden eines maximalen planaren Subgraphen sind NP-vollständig, d.h. die Probleme sind nicht in polynomieller Zeit lösbar. Die Lösung solcher Probleme wird deshalb durch Heuristiken möglichst gut abgeschätzt. Durch den steigenden Gebrauch von Diagrammen in Wissenschaft und Wirtschaft, hat das automatische Zeichnen von Graphen stark an Bedeutung gewonnen. Diagramme unterstützen die Aussagekraft des zugrundeliegenden Modelles und erleichtern das Verständnis des dargestellten Sachverhaltes. Gerade in der Informatik werden sehr häufig Diagramme eingesetzt, z.b. Entity-Relationship-Diagramme (ERM) bei der Modellierung eines Datenbanksystems, UML-Diagramme bei der Softwareentwicklung, Syntaxdiagramme beim Compilerbau und Schaltpläne beim Entwurf von VLSI-Schaltungen (Very Large Scale Integration). Nahezu alle Diagrammtypen lassen sich durch Graphen repräsentieren und somit auch automatisch zeichnen. Dazu bildet man die Symbole eines Diagrammes auf Knoten und die Verbindungen auf Kanten eines Graphen ab und entwickelt dann einen geeigneten Layoutalgorithmus. Bei der Entwicklung muss neben der Qualität der Zeichnung auch auf die Laufzeit geachtet werden, da die Benutzer oft direkt auf die Ausgabe warten. Eine höhere

12 4 KAPITEL 1. EINFÜHRUNG Qualität verursacht oft auch eine höhere Laufzeit, es muss also das richtige Verhältnis zwischen Qualität und Laufzeit gefunden werden. Ziel dieser Diplomarbeit ist die Entwicklung und Implementierung eines Algorithmus zum automatischen Layout von UML-Klassendiagrammen. Dazu werden die spezifischen Ästhetikanforderungen von UML-Klassendia grammen ermittelt und dann in den Layoutalgorithmus mit einbezogen. Im Gegensatz zu den meisten bisherigen Ansätzen, die auf einem hierarchischen Layoutalgorithmus basieren, dient hier ein orthogonaler Layoutalgorithmus als Basis. Die wesentlichen Modifikationen, die in dieser Diplomarbeit behandelt werden, sind das Aufwärtszeichnen von Kanten und die Verwendung von Vererbungsgabeln zur Darstellung von Vererbungsbeziehungen. Die Implementierung des Layoutalgorithmus erfolgt in der Programmiersprache Java unter Verwendung der yfiles-klassenbibliothek. Als Ausgangspunkt dient das bestehende Kandinsky-Framework. 1.2 Überblick Im nächsten Kapitel werden die grundlegenden graphentheoretischen Begriffe erläutert, die in den folgenden Kapiteln vorausgesetzt werden. Kapitel 3 gibt einen Überblick über die UML-Notation und die sich daraus ergebenden Anforderungen an den Layoutalgorithmus. Die Beschreibung verschiedener Ästhetikkriterien sowie die Untersuchung deren Relevanz in Bezug auf UML-Klassendiagramme erfolgt in Kapitel 4. In Kapitel 5 werden bestehende Algorithmen zum Erzeugen orthogonaler Zeichnungen vorgestellt, die als Basis für den zu entwickelnden Algorithmus dienen. Die Anpassungen und Modifikationen, die zum Zeichnen von UML-Klassendiagrammen erforderlich sind, werden in Kapitel 6 beschrieben. Implementierungsspezifische Designentscheidungen liefert Kapitel 7. Schließlich werden die ermittelten Ergebnisse im 8. Kapitel nochmals zusammengefasst bevor eine Bewertung des entwickelten Layoutalgorithmus erfolgt. Anhang A enthält einige Beispieldiagramme, die mit dem entwickelten Layoutalgorithmus gezeichnet wurden. Es wurden Beispieldiagramme gewählt, die die Wirkung der einzelnen Modifikationen verdeutlichen.

13 Kapitel 2 Grundlagen In diesem Kapitel werden einige grundlegende Begriffe erläutert, die im Laufe dieser Arbeit verwendet werden. 2.1 Graphen Die in diesem Abschnitt verwendeten Definitionen stammen im wesentlichen aus [4] und [7]. Ein Graph G ist ein geordnetes Paar (V, E) zweier Mengen, wobei V die Menge der Knoten und E die Menge der Kanten ist. Die Kantenmenge E setzt sich aus gerichteten Kanten E D und ungerichteten Kanten E U zusammen. Es gilt: E = E D E U. Eine gerichtete Kante e E D ist ein geordnetes Paar (v, w) und eine ungerichtete Kante e E U ist ein ungeordnetes Paar (v, w), wobei v, w V. Bei ungerichteten Kanten spielt die Angabe der Reihenfolge der Knoten keine Rolle, d.h. die ungerichtete Kante (v, w) kann auch durch (w, v) angegeben werden. Die Knoten v und w einer Kante e = (v, w) werden als Endpunkte der Kante bezeichnet. Sind die beiden Endpunkte einer Kante identisch, dann nennt man diese Kante eine Selbstschleife (Selfloop). Existieren mehrere Kanten mit denselben Endpunkten, so nennt man diese Mehrfachkanten. Eine Kante e ist inzident zu einem Knoten v, wenn v ein Endpunkt der Kante ist. Ein Knoten v ist adjazent zum Knoten w falls (w, v) E. Ein Knoten v ist benachbart zum Knoten w falls (v, w) E oder (w, v) E. Ein zu v adjazenter Knoten ist also immer auch ein Nachbar von v, die Umkehrung gilt nur bei ungerichteten Kanten. Ein Graph G = (V, E) wird gerichteter Graph genannt, falls gilt E = E D. Gilt E = E U so nennt man G einen ungerichteten Graph. Ist der Graph G weder gerichtet noch ungerichtet, so nennt man ihn teilgerichtet. Ein Graph G = (V, E ) ist ein Subgraph von G = (V, E) falls gilt: V V und E E. Ist dabei V = V, dann wird G als Teilgraph von G bezeichnet. Der Graph G ist der von V V induzierte Subgraph von G, falls E alle Kanten aus E enthält, die Knoten aus V verbinden (v, w V (v, w) E (v, w) E ).

14 6 KAPITEL 2. GRUNDLAGEN Ein Graph G = (V, E) wird als bipartit bezeichnet, falls die Knotenmenge V in zwei disjunkte Knotenmengen V 1 und V 2 aufgeteilt werden kann, so dass gilt V = V 1 V 2, V 1 V 2 = und für alle Kanten (v, w) E gilt: (v V 1 w V 2 ) oder (v V 2 w V 1 ). Der Grad δ(v) eines Knotens v gibt die Anzahl der zu v inzidenten Kanten an. Eine Selbstschleife wird dabei doppelt gezählt. Bei gerichteten Graphen G unterscheidet man zusätzlich zwischen dem Ausgangsgrad δ out (v) = {w : (v, w) E} und dem Eingangsgrad δ in (v) = {w : (w, v) E}. Es gilt dann δ(v) = δ in (v) + δ out (v). Der Grad eines Knotens v bezüglich der Kantenmenge E wird mit δ E (v) bezeichnet und gibt die Anzahl der zu v inzidenten Kanten e an, für die gilt e E. Ein Graph G wird als k-graph bezeichnet falls gilt: max v V δ(v) k. Ein Graph G = (V, E) ist zum Graphen G = (V, E ) isomorph, falls eine bijektive Funktion f : V V existiert, so dass (u, v) E (f(u), f(v)) E. Ein Pfad p von einem Knoten v zu einem Knoten w im Graphen G = (V, E), besteht aus einer Knotenfolge (v 0,.., v k ), wobei gilt: v 0,.., v k V, v 0 = v, v k = w und (v i, v i+1 ) E für alle i = 0,.., k 1. Die Länge des Pfades p ist gleich der Anzahl der abgelaufenen Kanten. Sind die Knoten v 0,.., v k paarweise verschieden, dann nennt man P einen einfachen Pfad. Ist v 0 = v k dann bildet der Pfad einen Zyklus. Ein Graph G ist azyklisch, falls kein Knotenpaar (v, w) in G existiert, dass durch einen einfachen zyklischen Pfad verbunden ist. Ein ungerichteter Graph G ist zusammenhängend, falls für jedes Knotenpaar v, w V, v w ein Pfad von v nach w in G existiert. Ein zusammenhängender, azyklischer und ungerichteter Graph wird auch als Baum 1 bezeichnet. Ein Spannbaum (spanning tree) von G ist ein Baum, der Teilgraph von G ist und ( V 1) Kanten enthält. Ein gewurzelter Baum (rooted tree) ist ein Baum mit einem ausgezeichneten Knoten r, der als Wurzel des Baumes bezeichnet wird. Sei r die Wurzel eines Baumes T = (V, E) und v V ein Knoten. Alle Knoten w V auf dem Pfad von r nach v werden als Vorgänger von v bezeichnet. Ist w ein Vorgängerknoten von v, dann ist v ein Nachfolger von w. Der Subbaum von v, ist der Baum, der durch die Nachfolgerknoten von v induziert wird, wobei v die Wurzel des Baumes ist. Ist w ein Vorgänger von v und gilt (w, v) E, dann ist w der Vater von v und v das Kind von w. Besitzen zwei Knoten den gleichen Vater, dann sind sie Geschwister. Ein Knoten ohne Kind ist ein Blatt. Jeder Knoten außer der Wurzel besitzt genau einen Vater. 2.2 Planarität Eine ebene Einbettung eines Graphen G = (V, E) ist eine Abbildung von G in den R 2, für die gilt [30]: 1 Der Graph kann auch gerichtete Kanten besitzen, diese werden aber wie ungerichtete Kanten behandelt.

15 2.2. PLANARITÄT 7 Die Knotenmenge V wird auf verschiedene Punkte der Fläche abgebildet. Die Kantenmenge E wird auf offene Jordan-Kurven abgebildet, wobei jede Kurve die zwei Punkte der Fläche verbindet, auf die die Endpunkte der entsprechenden Kante abgebildet werden. Es existiert kein Paar von Kurven, das sich überschneidet. Ein Graph für den eine ebene Einbettung existiert, kann also überkreuzungsfrei gezeichnet werden. Definition 1 (Planarität) Ein Graph ist planar, wenn für ihn eine ebene Einbettung existiert. Bei der Definition der Planarität spielt es keine Rolle, ob es sich bei dem Graphen um einen gerichteten oder ungerichteten Graphen handelt. Für jeden planaren Graphen existiert eine kreuzungsfreie Zeichnung. Der Begriff der Planarität ist allerdings unabhängig von der Zeichnung eines Graphen. Ein Graph, der in einer Zeichnung Kreuzungen besitzt, kann also trotzdem planar sein. Eine ebene Einbettung eines Graphen G = (V, E) teilt die Ebene in verschiedene Regionen auf. Diese Regionen werden Faces genannt. Es existiert dabei genau ein unbeschränktes Face, dass sogenannte äußere Face. Jede Kante grenzt zwei, nicht notwendigerweise verschiedene Faces voneinander ab. Sind die beiden Faces identisch, dann nennt man die Kante eine Brücke. Ein Face kann niemals von einem anderen Face geschnitten werden, es kann aber in einem anderen Face enthalten sein. Die planare Repräsentation P eines eben eingebetteten Graphen G beschreibt dessen Topologie. Für jedes Face f von G besitzt die planare Repräsentation P eine Liste P (f), die die Kanten enthält, die das Face f begrenzen. Ist f ein inneres Face, dann entspricht die Reihenfolge der Kanten der zyklischen Reihenfolge, die entsteht, wenn die Kanten von f im Uhrzeigersinn durchlaufen werden. Ist f das äußere Face, entspricht die Reihenfolge der Kanten der zyklischen Reihenfolge, die entsteht, wenn die Kanten von f gegen den Uhrzeigersinn durchlaufen werden. Dadurch kann die Repräsentation des äußeren Faces von der des inneren Faces unterschieden werden, falls beide Faces die gleiche begrenzende Kantenmenge besitzen. Da nicht festgelegt wird, mit welcher Kante eine Liste P (f) beginnen muss, ist die planare Repräsentation nicht eindeutig. Enthält ein Face f eine Brücke e, so ist e zweimal in der Kantenmenge der Liste P (f) enthalten (die Kante e wird dabei in unterschiedliche Richtungen abgelaufen). Jede Kante erscheint also genau zweimal in den Listen. Es gilt demnach: P (f) = 2 E. (2.1) f F

16 8 KAPITEL 2. GRUNDLAGEN Der Grad eines Faces f wird mit δ(f) bezeichnet und gibt die Anzahl der Kanten an, die das Face begrenzen. Es gilt also δ(f) = P (f). Damit das äußere Face eindeutig bestimmt ist, wird es in der planaren Repräsentation entsprechend gekennzeichnet. Die Angabe der Listen P (f) ist äquivalent zur Angabe der zyklischen Ordnung der Kanten um die Knoten. Ein Beispiel für eine planare Repräsentation zeigt Abb e 2 e v 7 3 v 6 e v 1 1 v2 e 3 f 3 e 4 f 2 e 6 v4 e 5 v 5 f 1 =äußeres Face P(f 1 )=(e 2, e 3, e 5, e 6, e 7 ) P(f 2 )=(e 6, e 5, e 4, e 7 ) P(f 3 )=(e 1, e 1, e 2, e 4, e 3 ) f 1 Abbildung 2.1: Beispiel einer planaren Repräsentation. Die Kante e 1 ist eine Brücke, das Face f 1 ist das äußere Face. Eine wichtige Eigenschaft von planaren Graphen zeigt die Eulersche Formel. Satz 1 (Eulersche Formel) Sei G = (V, E) ein zusammenhängender, eben eingebetteter Graph und F die Menge der Faces von G. Dann gilt: V E + F = 2. Ein Beweis zu diesem Satz befindet sich in [20]. Aus der Eulerschen Formel ergibt sich u.a., dass sich die Anzahl der Kanten in einem zusammenhängenden, planaren Graphen linear zur Anzahl der Knoten verhält, denn unter Nichtberücksichtigung von Selbstschleifen und Mehrfachkanten gilt: P (f) 3 für alle f F und wegen Formel 2.1 gilt damit F 2 3 E. Nach Einsetzen in die eulersche Formel ergibt sich E 3 V 6. Falls sich die Anzahl der Mehrfachkanten linear zu der Anzahl der Knoten verhält, gilt also: E = O( V ). Diese Eigenschaft wird häufig für die Laufzeitabschätzung von Algorithmen auf zusammenhängenden, planaren Graphen verwendet. Für azyklische, gerichtete Graphen wird der Begriff der Planarität oft zum Begriff der Aufwärtsplanarität verfeinert. Definition 2 (Aufwärtsplanarität) Ein gerichteter Graph G ist aufwärtsplanar, wenn er so eben eingebettet werden kann, dass alle Kanten monoton steigend in eine Richtung zeigen. Die Richtung der Kanten muss dabei nicht unbedingt aufwärts sein, sie müssen lediglich in dieselbe Richtung zeigen. Die Richtung selbst ist beliebig, da

17 2.3. ORTHOGONALE ZEICHNUNGEN VON PLANAREN GRAPHEN 9 die Zeichnung entsprechend gedreht werden kann. Aus der Definition ergibt sich direkt, dass ein aufwärtsplanarer Graph G auch immer planar und azyklisch sein muss. Die Umkehrung gilt nicht (vgl. Abb. 2.2). Ein teilgerichteter Graph G = (V, E D E U ) ist aufwärtsplanar, wenn der durch die Kanten E D induzierte Subgraph von G aufwärtsplanar ist (a) (b) Abbildung 2.2: Der dargestellte Graph ist zwar planar (a) aber nicht aufwärtsplanar, da die aufwärtsgerichtete Zeichnung (b) eine Kreuzung besitzt. 2.3 Orthogonale Zeichnungen von planaren Graphen Ein orthogonales Gitter ist eine ebene Einbettung eines unendlichen 4-Graphs, dessen Knoten ganzzahlige Koordinaten besitzen und dessen Kanten Knotenpaare mit einer Einheitsdistanz verbinden [30]. Eine orthogonale Gittereinbettung eines Graphen G = (V, E) ist eine Abbildung Q von G in das orthogonale Gitter, für die gilt: Jeder Knoten von G wird auf einen unterschiedlichen Punkt des Gitters abgebildet. Für zwei Knoten v, w V, v w gilt also: Q(v) Q(w). Jede Kante e = (v, w) von G wird auf einen Pfad Q(e) des Gitters abgebildet, dessen Endpunkte Q(v) und Q(w) sind. Die Pfade Q(e 1 ) und Q(e 2 ) eines beliebigen Kantenpaares e 1, e 2 E besitzen keine gemeinsamen Punkte, außer gegebenenfalls gemeinsame Endpunkte. Ein eben eingebetteter Graph Q(G), der von Q beschrieben wird, ist isomorph zu G. Die horizontalen und vertikalen Abschnitte, aus denen sich

18 10 KAPITEL 2. GRUNDLAGEN eine Kante zusammensetzt, werden Segmente der Kante genannt. Alle Winkel einer orthogonalen Gitterzeichnung sind ein Vielfaches von 90 Grad. Ein Endpunkt eines Segments, auf den kein Knoten abgebildet wird, wird als Knick bezeichnet. Eine Gittereinbettung Q wird als regionerhaltend bezüglich P bezeichnet, wenn die planare Repräsentation von Q(G) isomorph zu P ist. Abb. 2.3 zeigt eine orthogonale Gittereinbettung eines vollständigen Graphen mit vier Knoten. Abbildung 2.3: Orthogonale Gittereinbettung eines Graphen. Die Form eines orthogonalen Graphen G wird durch die orthogonale Repräsentation H beschrieben. Diese erweitert die planare Repräsentation um Informationen über Winkel zwischen Kanten sowie über Kantenknicke. Die orthogonale Repräsentation H eines planaren 4-Graphen G mit der planaren Repräsentation P enthält für jedes Face f von G eine Liste H(f). Ein Listenelement enthält folgende Einträge: 1. eine Kante e von G, 2. eine binäre Zeichenkette s (Bitvektor), 3. und eine Zahl a aus der Menge {90, 180, 270, 360}. Die Liste H(f) erhält man, indem man die Liste P (f) um die Punkte 2) und 3) erweitert. Die Kanten e von H(f) entsprechen also den Kanten von P (f). Die binäre Zeichenkette s beschreibt die Form der Kante e. Eine 0 kodiert einen Winkel von 90 Grad, eine 1 einen Winkel von 270 Grad. Das k-te Bit von s gibt den Winkel des k-ten Knickes der Kante e an, auf den man trifft, wenn man e im Face f im Uhrzeigersinn bzw. gegen den Uhrzeigersinn, falls f das äußere Face ist, abläuft. Besitzt die Kante e keinen Knick, wird dies durch ein ε symbolisiert. Die Zahl a gibt den Winkel zwischen der Kante e und der Kante des in H(f) folgenden Listenelements an. Abb. 2.4 zeigt ein Beispiel einer orthogonalen Repräsentation. Die orthogonale Repräsentation H eines orthogonalen Graphs besitzt die folgenden Eigenschaften:

19 2.3. ORTHOGONALE ZEICHNUNGEN VON PLANAREN GRAPHEN11 e v 7 3 v 6 e 2 v2 f 3 e 4 f 2 e 6 e 1 v1 e 3 v4 v 5 e 5 f 1 f 1 =äußeres Face H(f 1 )=((e 2, 11, 180), (e 3, ɛ, 180), (e 5, ɛ, 270), (e 6, ɛ, 270), (e 7, ɛ, 180)) H(f 2 )=((e 6, ɛ, 90), (e 5, ɛ, 90), (e 4, ɛ, 90), (e 7, ɛ, 90)) H(f 3 )=((e 1, ɛ, 360), (e 1, ɛ, 90), (e 2, 00, 90), (e 4, ɛ, 90), (e 3, ɛ, 90)) Abbildung 2.4: Beispiel einer orthogonalen Repräsentation. Die Knicke werden der Kante e 2 zugewiesen. 1. Es existiert ein planarer 4-Graph, dessen planare Repräsentation durch die e-felder von H(f) gegeben ist. 2. Seien r 1 H(f i ) und r 2 H(f j ) zwei unterschiedliche Listenelemente und r 1.e = r 2.e (e trennt die Faces f i und f j ). Dann entspricht die binäre Zeichenkette r 1.s der binären Zeichenkette die man erhält, wenn man r 2.s umkehrt und dann negiert (vgl. Abb. 2.5). 3. Für jedes Listenelement r sei Rotation(r) = Zeros(r.s) Ones(r.s) + (2 r.a 90 ), wobei Zeros die Anzahl der Nullen und Ones die Anzahl der Einsen in der binären Zeichenkette s angibt. Da jedes von H beschriebene Face ein rektilineares Polygon bildet, gilt: r H(f) Rotation(r) = { 4 f ist äußeres Face, +4 sonst. 4. Sei L v die Menge der Listenelemente r für die v ein Endpunkt der Kante r.e ist und r.e bezüglich der entsprechenden Liste H(f) in Richtung des Knotens v durchlaufen wird. Für jeden Knoten v gilt dann: r L v r.a = 360

20 12 KAPITEL 2. GRUNDLAGEN Die Summe der Winkel von benachbarten Kanten um einen Knoten v ist also 360 Grad. Um aus einer orthogonalen Repräsentation eine orthogonale Gittereinbettung zu erhalten, muss noch die Länge der Kantensegmente berechnet werden. 1 f i e f j Abbildung 2.5: Zusammenhang der Zeichenketten. Durchläuft man die Kante e im Face f j, so entsteht die Zeichenkette 110. Durchläuft man e im Face f i, so entsteht die Zeichenkette 100. Mit der orthogonalen Repräsentation lassen sich bis jetzt nur 4-Graphen beschreiben. Ein Knoten v mit δ(v) > 4, besitzt in einer orthogonalen Zeichnung mindestens eine Seite an der sich mehrere Kanten befinden. Der von diesen Kanten eingeschlossene Winkel ist somit ein 0 Grad Winkel. Um 0 Grad Winkel in die orthogonale Repräsentation mit aufzunehmen, erlaubt man für die Zahl a, die den Winkel angibt, auch einen Wert von 0. Eine orthogonale Repräsentation, die 0 Grad Winkel zulässt, wird quasi-orthogonale Repräsentation genannt. 2.4 Min-Cost-Flow Das Finden einer knickminimalen orthogonalen Repräsentation erfolgt durch das Lösen eines Min-Cost-Flow-Problems, welches ein Netzwerkflussproblem darstellt. Ein Netzwerk N = (V, E) ist ein gerichteter Graph mit zwei ausgezeichneten Knoten, einer Quelle s und einer Senke t, wobei gilt: δ in (s) = 0 und δ out (t) = 0. Auf der Menge der Kanten wird eine nichtnegative Funktion cap: E R 0 definiert, welche die Kapazität der Kanten angibt. Für alle Knoten v, w V (v, w) / E gilt: cap(v, w) = 0. Ein Fluss im Netzwerk N ist eine Funktion f : V V R, die folgende Eigenschaften besitzt: (1) f(v, w) = f(w, v) für alle Knoten v, w V, (2) f(v, w) cap(v, w) für alle Knoten v, w V,

21 2.4. MIN-COST-FLOW 13 (3) f(v, w) = 0 w V für alle Knoten v V \ {s, t}. Eigenschaft (1) wird als Schiefsymmetrie bezeichnet. Durch die Kapazitätsbedingung (2) wird der Fluss, der über eine Kante fließen kann, durch deren Kapazität beschränkt. Die Flusserhaltungsbedingung (3) sagt aus, dass für jeden Knoten v V \ {s, t} der gesamte Fluss in den Knoten hinein gleich dem gesamten Fluss aus dem Knoten heraus ist. Der Wert f eines Flusses f entspricht dem Fluss aus dem Quellknoten heraus. Es gilt also: f = v V f(s, v). Ein Fluss f ist maximal, wenn sein Wert f mindestens so groß ist, wie der Wert jedes anderen Flusses. Bei einem Min-Cost-Flow-Problem wird zusätzlich eine Kostenfunktion cost: E R auf den Kanten des Netzwerkes N definiert, welche die Kosten angibt, die beim Transport einer Flusseinheit über die Kante anfallen. Die Kosten eines Flusses f sind wie folgt definiert: cost(f) = e E f(e) cost(e). Ein Min-Cost-Flow ist ein maximaler Fluss minimaler Kosten.

22 14 KAPITEL 2. GRUNDLAGEN

23 Kapitel 3 Notation von UML-Klassendiagrammen Dieses Kapitel bietet einen Überblick über die wichtigsten Notationselemente von UML-Klassendiagrammen und basiert im wesentlichen auf [19] und [24]. Es existieren Elemente für Klassen, verschiedene Beziehungen und Pakete. Für die genauere Spezifizierung von Elementen besitzt die UML außerdem verschiedene eingebaute Erweiterungsmechanismen, wie Zusicherungen, Eigenschaften, Stereotypen und Notizen. Bei den genannten Erweiterungen handelt es sich, bis auf die Notiz, nicht um neue Elemente, sondern lediglich um eine geeignete Beschriftung der Grundelemente. Im folgenden werden zuerst die Grundelemente und dann die Erweiterungsmechanismen vorgestellt. 3.1 Klassen Eine Klasse wird durch ein Rechteck mit drei, jeweils durch horizontale Linien getrennte, Komponenten dargestellt. Die oberste Komponente enthält den Klassennamen in zentrierter, fetter Schrift. Handelt es sich um eine abstrakte Klasse, wird er zusätzlich kursiv geschrieben. Der Name beginnt mit einem Großbuchstaben. Die Komponente kann außerdem auch eine Erweiterung für die genauere Spezifizierung der Klasse enthalten. Stereotypen werden zentriert über dem Klassennamen angegeben. Die Angabe von Eigenschaften erfolgt unter dem Klassennamen. Die genauere Spezifizierung der Erweiterungen folgt in Abschnitt 3.4. Die mittlere Komponente enthält die Attribute einer Klasse. Ein Attribut wird durch folgende Syntax spezifiziert: Sichtbarkeit Name: Typ = Defaultwert {Eigenschaften}. Für die Sichtbarkeit (visibility) eines Elements kennt die UML folgende Werte:

24 16 KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN + für öffentliche (public) Sichtbarkeit. Ein solches Element ist für alle Klassen sichtbar. # für geschützte (protected) Sichtbarkeit. Ein solches Element ist nur innerhalb der definierenden Klasse und in deren Unterklassen sichtbar. - für private (private) Sichtbarkeit. Ein solches Element ist nur innerhalb der definierenden Klasse sichtbar. Eine fehlende Sichtbarkeitsangabe bedeutet lediglich, dass die Angabe unterdrückt wird, nicht das die Sichtbarkeit nicht definiert ist. Der Name eines Attributs wird üblicherweise klein geschrieben. Für die Angabe des Typs wird meistens die entsprechende Typbezeichnung der verwendeten Programmiersprache benutzt. Besitzt ein Attribut keinen Defaultwert, so folgt die Angabe der Eigenschaften direkt nach der Angabe des Typs. Als Eigenschaften können dabei auch Zusicherungen angegeben werden. Werden Stereotypen angegeben, stehen diese vor der Sichtbarkeitsangabe. Es besteht auch die Möglichkeit, Stereotypen oder Eigenschaften über einem Attributelement anzugegeben. Sie gelten dann für sämtliche Elemente bis zur nächsten Angabe. Die unterste Komponente enthält die Methoden der Klasse. Methoden 1, die lediglich zum setzen und lesen von Attributwerten dienen, werden häufig weggelassen. Die Syntax für die Darstellung einer Methode lautet: Sichtbarkeit Name (Parameter) : Rückgabetyp {Eigenschaften}. Für die Angabe der Sichtbarkeit, der Eigenschaften und der Stereotypen gilt dasselbe wie bei den Attributen. Der Name einer Methode entspricht meist dem Methodennamen in der Implementierung. Die Angabe der Parameter und des Rückgabetyps ist optional. Werden Parameter angegeben, besitzen sie folgende Syntax: Art Name: Implementierungstyp = Defaultwert. Für die Art eines Parameters sind folgende Werte zulässig: in für Eingabeparameter, out für Ausgabeparameter, inout falls beides zutrifft. Für den Implementierungstyp und den Defaultwert gilt dasselbe wie bei den Attributen. Werden mehrere Parameter angeben, so werden diese durch Komma getrennt. Eine abstrakte Methode kann durch die Eigenschaft {abstract} oder durch Kursivschrift der Signatur gekennzeichnet werden. 1 Die Begriffe Methode und Operation werden hier nicht unterschieden.

25 3.2. BEZIEHUNGEN 17 Der Gültigkeitsbereich (scope) gibt an, ob ein Attribut oder eine Methode statisch (static members) ist. Ein statisches Attribut (Klassenattribut) existiert nur einmal und unabhängig von den Instanzen der Klasse. Eine statische Methode (Klassenmethode) operiert auf der Klasse und nicht auf einem Objekt. Klassenattribute und -methoden werden unterstrichen dargestellt. Wenn die Angabe der Attribute oder Methoden nicht erforderlich ist, können die entsprechenden Komponenten weggelassen werden. Außerdem können benutzerdefinierte Komponenten angefügt werden, wie z.b. eine Komponente für die Angabe von Ausnahmen (exceptions). In Abbildung 3.1 werden verschiedene Darstellungen von Klassen gezeigt. Klasse A +nummer: int = 0 -flag: boolean = false +setzeflag(in flag:boolean) #berechnewert(): int Subklasse #berechnewert(): int (a) (b) «interface» Schnittstelle (c) Abbildung 3.1: Darstellung einer Klasse in UML-Klassendiagrammen. 3.2 Beziehungen Klassendiagramme können verschiedene statische Beziehungsarten darstellen. Dazu gehören Vererbung, Assoziation und Abhängigkeit Vererbung (inheritance) Die Vererbung beschreibt Generalisierungs- und Spezialisierungsbeziehungen, d.h. Beziehungen zwischen einer allgemeineren und einer spezifischeren Klasse. Die allgemeinere Klasse wird als Superklasse (Oberklasse) und die spezifischere als Subklasse (Unterklasse) bezeichnet. Eine Subklasse erbt alle Eigenschaften (Attribute und Methoden) ihrer Superklasse und kann darüber hinaus noch weitere Eigenschaften definieren. Eine Instanz der Subklasse kann somit auch als Instanz der Superklasse verwendet werden (Polymorphismus). Die Subklasse zeigt geerbte Eigenschaften im Klassendiagramm

26 18 KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN nur nochmals an, falls sie diese geändert hat, z.b. beim Überschreiben einer Methode (vgl. Abb. 3.1(b)). Die Vererbungsbeziehung wird durch eine Linie zwischen der Subklasse und der Superklasse repräsentiert, wobei das Linienende an der Superklasse mit einem transparenten Dreieck versehen wird, dessen Spitze auf die Superklasse zeigt. Dieselbe Darstellung wird auch für die Schnittstellenvererbung verwendet, d.h. wenn sowohl die Sub- als auch die Superklasse eine Schnittstelle ist. Wird eine Schnittstelle von einer Klasse implementiert, d.h. die Superklasse ist eine Schnittstelle und die Subklasse eine gewöhnliche Klasse, dann wird die Vererbungslinie gestrichelt gezeichnet (vgl. Abb. 3.2(b)). Besitzt eine Superklasse mehrere Subklassen, dann können die Vererbungslinien auch als Vererbungsgabel dargestellt werden (vgl. Abb. 3.2(a)). Eine Vererbungslinie kann außerdem durch einen Diskriminator beschriftet werden. Dieser gibt das Unterscheidungsmerkmal der Subklassen an, das für die Bildung der Vererbungshierarchie ausschlaggebend war. Die Subklassen einer Superklasse können auch unterschiedliche Diskriminatoren besitzen. Beim Verwenden von Vererbungsgabeln werden Stereotypen und Eigenschaften am Linienende der Superklasse platziert. Ansonsten werden sie an einer gestrichelten Linie platziert, die alle beteiligten Vererbungslinien kreuzt. Superklasse «interface» Schnittstelle Subklasse 1 Subklasse 2 Subklasse 3 Klasse 1 Klasse 2 (a) (b) Klasse 1 Rolle 1 1 Klasse 1 Ganzes 2 Klasse 1 Ganzes 1 Klasse 1 Assoziation Aggregation Komposition Abhängigkeit Rolle ,4 Klasse 2 Teil 0..5 Klasse 2 Teil 0..5 Klasse 2 Klasse 2 (c) (d) (e) (f) Abbildung 3.2: Darstellung von Beziehungen in UML-Klassendiagrammen.

27 3.2. BEZIEHUNGEN Assoziation (association) Eine Assoziation beschreibt die Beziehung zwischen Instanzen (Objekte) von Klassen. Sie wird durch eine Linie dargestellt, die die beteiligten Klassen verbindet (vgl. Abb. 3.2(c)). Eine Assoziation drückt eine Bekanntschaft der beteiligten Objekte aus. Meistens kennen sich die Objekte gegenseitig, man spricht dann von einer bidirektionalen Assoziation. Bei einer unidirektionalen Assoziation gilt die Bekanntschaft nur in eine Richtung. Die Assoziationslinie wird dann mit einer Pfeilspitze versehen, so das der Pfeil vom wissenden zum unwissenden Objekt zeigt. Man spricht dabei auch von Navigierbarkeit (navigability) in eine bzw. in beide Richtungen. Die Assoziationslinie kann außerdem mit einem Assoziationsnamen beschriftet werden. Um die Leserichtung der Assoziation zu bestimmen, kann beim Assoziationsname ein Pfeil in Form eines gefüllten Dreiecks angebracht werden. Bei einer binären Assoziation sind genau zwei Klassen an einer Beziehung beteiligt. Steht eine Klasse zu sich selbst in Beziehung, handelt es sich um eine reflexive Assoziation. Die verschiedenen Instanzen der Klasse, die an der reflexiven Assoziation beteiligt sind, nehmen dabei unterschiedliche Rollen ein. Eine Rolle gibt die Bedeutung einer Klasse innerhalb der Assoziation an. Der Rollenname steht an dem Ende der Assoziationslinie, an dem sich die beschriebene Klasse befindet. Vor dem Rollenname kann eine Sichtbarkeitsangabe wie bei Attributen und Methoden stehen. Auf die explizite Angabe einer Rolle kann verzichtet werden, falls diese aus dem Klassennamen abgeleitet werden kann. Existieren mehrere Assoziationsbeziehungen zwischen zwei Klassen oder handelt es sich um eine reflexive Assoziation, so muss die Rolle stets explizit angegeben werden. Assoziationslinien, Rollennamen und Assoziationsnamen können außerdem durch Zusicherungen, Eigenschaften oder Stereotypen genauer spezifiziert werden. Die Angabe erfolgt jeweils in der Nähe der entsprechenden Komponente. Die Kardinalität (multiplicity) gibt an, wieviele Objekte einer Klasse A an einer Beziehung zu einem Objekt der Klasse B beteiligt sind. Die Kardinalität steht dabei an dem Ende der Assoziationslinie, an der sich die Klasse A befindet. Sie wird dabei in folgendem Format angegeben: untere-schranke.. obere-schranke. Die untere Schranke gibt die minimale Anzahl und die obere Schranke die maximale Anzahl, der an der Beziehung beteiligten Objekte an. Wird nur ein einzelner Wert angegeben, bedeutet dies, dass die untere Schranke gleich der oberen Schranke ist. Es sind auch durch Komma getrennte Kombinationen dieser Angaben möglich (z.b. 1..3,5,7.. ). Ein Stern gibt an, dass beliebig viele Objekte an einer Beziehung teilnehmen können. Bei einer unteren Schranke von 0 existiert eventuell gar keine Beziehung zu einem anderen Objekt.

28 20 KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN Eine Assoziation kann selbst Attribute und Methoden sowie Assoziationen zu anderen Klassen besitzen. Dies kann durch eine Assoziationsklasse modelliert werden. Die Darstellung einer Assoziationsklasse unterscheidet sich nicht von der Darstellung einer gewöhnlichen Klasse. Die Assoziationsklasse wird aber durch eine gestrichelte Linie mit der Assoziationslinie verbunden. Es existieren zwei Spezialfälle von Assoziationsbeziehungen, die Aggregation und die Komposition. Die Aggregation beschreibt eine Beziehung, bei der ein Objekt A Teil eines anderen Objekts B ist. Die Klasse des Objekts A wird bezüglich der Aggregation als Teilklasse bezeichnet, die Klasse des Objekts B als Aggregatsklasse. Die Unterscheidung zwischen Assoziation und Aggregation ist nicht immer einfach. Man spricht aber grundsätzlich nur dann von Aggregation, wenn das Teil ein fester Bestandteil des Ganzen ist. Die Aggregation wird durch einen transparenten Diamanten am Ende der Assoziationslinie der Aggregatsklasse dargestellt (vgl. Abb. 3.2(d)). Bei einer Komposition wird der Diamant gefüllt gezeichnet (vgl. Abb. 3.2(e)). Die Komposition stellt einen Sonderfall der Aggregation dar mit den folgenden Eigenschaften: Ein Teil existiert nur höchstens so lange wie das Ganze. Beim Löschen des Ganzen werden auch die Teile gelöscht. Die Kardinalität der Aggregatsklasse darf nicht größer als eins sein (strong ownership) Abhängigkeit (dependency) Eine Abhängigkeit ist ein Beziehung zwischen zwei Elementen, bei der die Änderung des einen Elements möglicherweise auch eine Änderung des anderen Elements (abhängiges Element) erforderlich macht. Bei einer Abhängigkeit stehen die Elemente selbst in Beziehung zueinander, unabhängig von den Instanzen. Abhängigkeiten werden durch einen gestrichelten Pfeil dargestellt, wobei sich das abhängige Element am Fuß des Pfeils befindet (vgl. Abb. 3.2(f)). Der Pfeil kann durch einen Namen oder einen Stereotyp beschriftet werden. Abhängigkeiten, die durch andere Beziehungsarten impliziert werden, werden normalerweise nicht nochmals gesondert dargestellt. 3.3 Pakete (packages) Pakete dienen der Gruppierung von Elementen. Ein Paket ist eine Art benannter Behälter für Elemente und kann auch weitere Pakete enthalten. Bei einer geeigneten Gruppierung sorgen Pakete für ein übersichtliches System. Pakete werden durch ein Rechteck mit Reiter dargestellt (wie ein Aktenordner). Wird der Inhalt des Pakets angezeigt, steht der Paketname im Reiter, ansonsten wird er innerhalb des Rechtecks platziert (vgl. Abb. 3.3).

29 3.4. ERWEITERUNGSMECHANISMEN 21 Stereotypen werden über den Paketnamen und Eigenschaften oder Zusiche- Paket 1 Paket 2 Klasse 1 Klasse 2 Abbildung 3.3: Darstellung von Paketen in UML-Klassendiagrammen. rungen hinter oder unter dem Paketnamen angegeben. Ein Paket definiert einen Namensraum. Die in einem Paket enthaltenen Klassen- und Paketnamen müssen eindeutig sein, es können aber Klassen oder Pakete mit gleichem Namen in verschiedenen Paketen existieren. Eine Referenz zu einer Klasse in einem anderen Paket wird durch Paketname::Klassenname angegeben. Da Pakete ineinander verschachtelt sein können, kann der Pfad zu einer Klasse aus mehreren durch :: getrennten Paketnamen bestehen. Der qualifizierte Name einer Klasse, der aus Paketpfad und Klassenname besteht, ist also immer eindeutig. Beziehungen zwischen Paketen werden durch Abhängigkeiten modelliert. 3.4 Erweiterungsmechanismen Die Anzahl verschiedener Notationselemente in Klassendiagrammen ist recht gering. Um dennoch möglichst viel Semantik in den Diagrammen unterbringen zu können, bietet die UML Erweiterungen für die Angabe von Zusicherungen, Eigenschaften, Stereotypen und Notizen an. Da es sich dabei, bis auf die Notiz, lediglich um eine geeignete Beschriftung der Grundelemente handelt, wird die Anzahl der verschiedenen Elemente weiterhin überschaubar gehalten Zusicherungen (constraints) Durch Zusicherungen kann man Einschränkungen und Invarianten für Elemente formulieren. Zusicherungen sind Ausdrücke, die stets wahr sein müssen. In der UML kann eine Zusicherung frei formuliert werden, sie muss dabei lediglich von geschweiften Klammern umschlossen sein. Falls z.b. ein Kunde einer Firma ein Mindestalter von 18 haben muss, kann dies durch die

30 22 KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN Zusicherung {Alter >= 18} ausgedrückt werden. Die Formulierung kann sowohl in Umgangssprache als auch durch einen Ausdruck einer Programmiersprache erfolgen. Inzwischen existieren auch spezielle Sprachen für die Formulierung von Zusicherungen, wie die Object Constraint Language (OCL). Neben den benutzerdefinierten Zusicherungen existieren auch bereits vordefinierte Zusicherungen in der UML. Einige davon werden in Tabelle 3.1 erläutert. Gilt eine Zusicherung für mehrere Elemente, kann sie sich auch in einer Notiz (s. Notizen auf S.23) befinden und durch gestrichelte Linien mit den entsprechenden Elementen verbunden werden. Zusicherung Element Bedeutung {complete} Vererbung Alle Subklassen wurden spezifiziert, es können keine weiteren hinzukommen. {ordered} Assoziation Menge der Objekte auf der Zielseite der Assoziation sind geordnet. {xor} Assoziation Objekt kann nur an einer der angegebenen Assoziationen beteiligt sein. Tabelle 3.1: Vordefinierte Zusicherungen der UML Eigenschaften (properties) Für die Angabe von Eigenschaften eines Elements, für die keine graphische Notation existiert, können benutzerdefinierte Eigenschaften verwendet werden. Diese werden als Schlüsselwort-Wert-Paare (tagged value) angegeben und wie Zusicherungen von geschweiften Klammern umschlossen. In einem Klammerpaar können mehrere durch Komma getrennte Eigenschaften stehen. Eine Eigenschaft besitzt folgende Syntax: Schlüsselwort = Wert. Das Schlüsselwort gibt den Namen der Eigenschaft an, der innerhalb des betreffenden Elementtyps eindeutig sein muss. Besitzt die Eigenschaft einen boolschen Typ, so ist ihr Defaultwert true, d.h. die Angabe des Wertes kann entfallen. Trifft eine Eigenschaft nicht zu (Wert = false) wird sie einfach nicht angegeben. Einige von der UML vordefinierte Eigenschaften werden in Tabelle 3.2 aufgezählt Stereotypen (stereotypes) Stereotypen ermöglichen die genauere Klassifizierung von Elementen. Ein Klassenelement repräsentiert z.b. sowohl eine normale Klasse wie auch eine

31 3.4. ERWEITERUNGSMECHANISMEN 23 Eigenschaft Element Bedeutung {abstract} Methode, Klasse Alternative Darstellung von abstrakten Klassen bzw. Methoden (anstatt kursivem Namen) {frozen} Attribut Ein einmal definierter Wert kann nicht mehr geändert werden {query} Methode Methode hat keine Seiteneffekte (Systemzustand bleibt erhalten) Tabelle 3.2: Vordefinierte Eigenschaften der UML. Schnittstelle. Durch die Angabe eines Stereotyps kann nun ein entsprechender Untertyp des Elements gebildet werden (vgl. Abb. 3.1(c)). Im Unterschied zu Eigenschaften, erweitern Stereotypen das Metamodell und somit die Modellierungssprache. Tabelle 3.3 zeigt einige von der UML vordefinierte Stereotypen und deren Bedeutung. Der Name eines Stereotyps wird stets von französischen Anführungszeichen («,») umschlossen. Neben vordefinierten Stereotypen können auch benutzerdefinierte eingeführt werden. Stereotyp Element Bedeutung «access» Abhängigkeit Quellpaket darf öffentliche Elemente des Zielpaketes referenzieren «constructor» Methode Methode ist ein Konstruktor «extends» Vererbung Vererbung um erweiterte Funktionalität anzubieten «interface» Klasse Klasse ist eine Schnittstelle «utility» Klasse Klasse besitzt nur statische Methoden und Attribute Tabelle 3.3: Vordefinierte Stereotypen der UML Notizen (notes) Wichtige Informationen über Elemente, die mit den bisher vorgestellten Erweiterungsmechanismen nicht dargestellt werden können, können durch Notizen in das Klassendiagramm aufgenommen werden. Eine Notiz dient jedoch nicht der Erweiterung der Semantik, sie wird lediglich zur genaueren Erläuterung eines Sachverhalts oder einer Entscheidung verwendet. Eine Notiz wird durch ein Rechteck mit einem Eselsohr in der rechten oberen Ecke dargestellt und kann beliebigen Text enthalten (vgl. Abb. 3.4). Sie kann durch eine gestrichelte Linie mit den betreffenden Elementen verbunden werden.