Info
Falls Sie uns noch nicht besucht haben: www.informatik-wahl.de. In der Rubrik "Service" gibt es noch mehr interessante Artikel.

Unsere aktuellen Schulungen:  Kurse


 
 
 

UML kompakt

von Günter Wahl

Erschienen im OBJEKTspektrum 2/1998
Alle Rechte vorbehalten

Der Artikel beschreibt die wesentlichen Stilelemente der "Unified Modeling Language" (UML) und gibt Hinweise für deren Anwendung. Dem Leser wird damit ein erster Einstieg in diese doch recht umfangreiche Sprache gegeben. Für die tägliche Praxis bedeutet dies, daß ein Verständnis für die UML geschaffen wird. Mit den hier vorgestellten Grundelementen ist der Leser in der Lage, ca. 90% seiner Probleme zu modellieren. Bei Bedarf kann er seine Kenntnisse durch zusätzliche Schulungen oder Literatur erweitern. Die Darstellung eines einfachen Prozesses in diesem Beitrag erleichtert die Orientierung. Derzeit gibt es nur wenig Literatur, die eine solche Orientierung in Verbindung mit einem Überblick darstellt.

Was ist die UML?

Die Unified Modeling Language (UML) ist eine Sprache zur Beschreibung von Softwaresystemen. Im Unterschied zu Methoden fehlen der UML eine Notation und Beschreibung für Prozesse. Prozesse für die Software sind ihrem Wesen nach vergleichbar mit solchen, die in der Industrie, z. B. zur Herstellung eines Arzneimittels, zu finden sind. Auch hier wird in industriellem Maßstab ein Gut, z. B. eine Kopfschmerztablette, hergestellt. Der Grundgedanke bei der UML bestand darin, eine einheitliche Notation für viele Einsatzgebiete zu haben. Die UML dient der Beschreibung von Datenbankanwendungen, Echtzeitsystemen, Grafikprogrammen, Workflow-Anwendungen usw. Kurz gesagt: Alle Softwaresysteme sollen mit der UML darstellbar sein.

Die UML besteht aus verschiedenen Diagrammen, die wiederum verschiedene graphische Elemente besitzen. Die Bedeutung, also die Semantik, der Elemente ist genau festgelegt. Innerhalb der UML gibt es allerdings für ein und denselben Sachverhalt manchmal mehrere Darstellungsarten.

In der UML sind mehrere Vorgängermethoden vereint: Die wichtigsten sind OOSE, OMT und Booch (vgl. [Jac92], [Rum91] und [Boo94]). Darüber hinaus bietet die UML eine Möglichkeit der Erweiterung, die durch "Stereotypen" erreicht wird. Ferner steht für die UML ein Metamodell zur Verfügung. Dieses ermöglicht es Herstellern von Softwarewerkzeugen, die UML richtig zu implementieren, und Kennern, die Sprache sinnvoll zu erweitern. Für Anfänger und Anwender ist das Metamodell unwichtig. Im folgenden werde ich es daher nicht mehr erwähnen.

Kurzgeschichte

Im Jahr 1988 begann die Geschichte der objektorientierten Methoden. Schon vorher gab es zahlreiche Methoden für die strukturierte Programmierung, die mit Erfolg in der Industrie eingesetzt wurden. Grundlage für die OO-Methoden waren die objektorientierten Sprachen, vorwiegend Smalltalk, später C++. Die Überlegung war, die Vorteile der strukturierten auf die objektorientierten Methoden zu übertragen.

Die wichtigsten OO-Methoden, die entstanden, waren:

Jede Methode hatte ihre eigenen Vor- und Nachteile. Durch die gegenseitige Übernahme von Konzepten aus anderen Methoden, versuchten einige, die Nachteile etwas auszugleichen.

1994 war für die UML - und wohl auch für die Geschichte der OO-Methoden - ein bedeutsames Jahr. Jim Rumbaugh verließ General Electric und ging zu Rational, wo bereits Grady Booch tätig war. Die beiden wollten ihre Methoden zusammenführen und erklärten, daß der Methodenkrieg nun vorbei sei. 1995 gaben sie die erste Veröffentlichung ihrer "Unified Method 0.8" heraus. Viel wichtiger in diesem Jahr war jedoch die Bekanntgabe, daß Rational die Firma Objectory gekauft hatte, und daß nun auch Ivar Jacobson für Rational arbeitete. Im Volksmund werden die drei "Amigos" genannt.

1996 begannen die Arbeiten an der UML. Im Jahr 1997 wurde die Version 1.0 bei der Object Management Group (OMG) als Standardisierungsvorschlag eingereicht, und eine Beschreibung der Version 1.0 wurde veröffentlicht. Im September 1997 wurde die Version 1.1 bei der OMG eingereicht, alle anderen Gegenvorschläge wurden zurückgezogen - in der Version 1.1 wurden Konzepte der Gegenvorschläge berücksichtigt.

Der Prozeß

Prozesse - wie sie in diesem Beitrag verstanden werden - dienen der industriellen Herstellung von Dingen, hier speziell von Softwaresystemen. Dafür gibt es verschiedene Modelle, die sich in der Praxis mehr oder weniger gut bewährt haben (z. B. Wasserfallmodell, V-Modell). Ein Prozeßmodell zu entwickeln, das auf alle realen Prozesse paßt, ist unmöglich. Deshalb wurde der Prozeß als solcher zunächst aus der UML ausgeklammert. Jedoch ist eine Softwareentwicklung ohne einen Prozeß unprofessionell.

In der UML wird deshalb versucht, ein Rahmenwerk für Prozesse zur Verfügung zu stellen. Rahmenwerk bedeutet, daß alle Vorgehensweisen und Notationen von konkreten Prozessen mit der Notation darstellbar sind. Damit können die Anwender und Manager ihre speziellen Prozesse mit der UML beschreiben. Hier bietet die UML also Flexibilität, muß aber an die jeweilige Situation angepaßt werden.

Veröffentlichungen über dieses Prozeßrahmenwerk gibt es bisher kaum. Grundlage dafür bildet jedoch die Beschreibung der OOSE-Methode von Jacobson und der darin beschriebene Prozeß "Objectory". Das Prozeßrahmenwerk der UML wird auch Objectory-Process genannt, in Anlehnung an den OOSE-Prozeß.

Eine weitere Beschreibung der UML, ohne eine Vorstellung von einem Prozeß im Hinterkopf zu haben, ist unprofessionell. Deshalb stelle ich hier einen einfachen Prozeß vor (vgl. [Fow97]). Der Entwicklungsprozeß soll aus vier Phasen bestehen (siehe auch Abb. 1):

Abb1: Einfacher Entwicklungsprozeß


In der Anforderungsphase werden die Funktionen und der Projektumfang grob abgesteckt. Die Festlegungsphase dient dazu, weitere Details zu bestimmen und ein High-Level-Design zu erstellen; außerdem wird eine Planung erstellt. Anschließend werden in der Erstellungsphase das System bzw. Teile davon gefertigt. Meist geschieht dies in einem iterativen Vorgehen: Nachdem ein Teil programmiert ist, wird getestet, anschließend werden weitere Funktionen hinzugefügt, getestet usw. (siehe Abb. 1, Pfeil n).

Hat das System einen gewissen Stand erreicht, kommt die Software in die Übergabephase. Hier wird eine Integration in das Gesamtsystem vorgenommen. Auch Optimierungen und Abnahmetests beim Kunden finden statt. Selbstverständlich werden erkannte Fehler beseitigt, jedoch wird keine Funktionserweiterung vorgenommen.

Insgesamt gesehen verläuft der Entwicklungsprozeß in mehreren Iterationen - er wird auch als "spiralförmig" oder "iterativ" bezeichnet (vgl. [Jac92]). Im Gegensatz dazu steht ein linearer Entwicklungsprozeß, dessen Modell als "Wasserfall" bezeichnet wird.

Beim spiralförmigen Entwicklungsprozeß werden alle Phasen mehrfach durchlaufen (siehe Abb. 1, Pfeil m). Dabei wird jedem Durchlauf eine Teilmenge der Kundenforderungen zugrundgelegt. Die Spirale wird solange durchlaufen, bis ein Endprodukt vorhanden ist. Alle Zwischenprodukte, die nach einem Durchlauf entstehen, sind voll funktionsfähig. Durch dieses Vorgehen wird erreicht, daß das System nicht in einer Art "Urknall", sondern in kleinen Schritten entsteht. Im folgenden können Sie sich einen Prozeß wie diesen für die Softwareentwicklung vorstellen. Somit gewinnen Sie eine Vorstellung, wie und wo die einzelnen Techniken einsetzbar sind.

Die Diagramme

Die Notation der UML umfaßt Diagramme für die Darstellung der verschiedenen Ansichten auf das System, vergleichbar mit Bauplänen für Häuser. Auch hier gibt es z. B. einen Grundriß, einen Lageplan, verschiedene Außenansichten und Werkpläne für die Handwerker. Für eine spezielle Aufgabe ist meist eine Diagrammart besser geeignet als andere.

Insgesamt umfaßt die UML

Hinzu kommen noch in jedem Diagramm zahlreiche Stilelement mit verschiedenen Beschriftungsarten. Insgesamt ist die UML also eine recht umfangreiche Sprache. Dies hat den Vorteil, daß mit der UML viel ausgedrückt werden kann, allerdings auch den Nachteil, daß die Sprache unübersichtlich und schwierig wird. Aber keine Angst! Alles ist eine Frage des Vorgehens und der Detailliertheit, in der ein System dargestellt werden soll.

Zum Vorgehen ist soviel zu sagen, daß bei weitem nicht alles modelliert werden soll. Ein Modell ist eine Ansicht der Realität, die den Zweck hat, einen bestimmten Sachverhalt darzustellen. So zeichnet beispielsweise ein Statiker ein Kräftediagramm, um die Kräfte in einem Dachbalken an einer bestimmten, wichtigen Stelle zu berechnen. Er zeichnet nicht für alle Balken an allen denkbaren Stellen Kräftediagramme - das wäre vollkommen überflüssig. Auch verwendet er ein Kräftediagramm und nicht die Außenansicht, die vielleicht schöner wäre, aber für diesen Zweck vollkommen ungeeignet ist.

Sich zu beschränken, ist eine Möglichkeit, die Komplexität, die sowohl der Methode als auch dem Softwaresystem innewohnt, zu beherrschen. Worauf sollte man sich beschränken? Hierauf eine allgemeine Antwort zu geben, ist nicht möglich. Der Modellierer muß über genügend Erfahrungen und Kenntnisse sowohl über den Fachbereich, als auch über sein Handwerkszeug - in unserem Fall die UML - verfügen.

Glücklicherweise bieten die UML und verschiedene Methoden, wie etwa die OMT, ein Grundrepertoire an, mit dem es möglich ist, alle praktisch wichtigen Problemstellungen in 90 Prozent der Fälle darzustellen. Nur selten werden weiterführende Stilelemente eingesetzt. Die Einsatzgebiete und Eigenschaften der Diagramme habe ich in Tabelle 1 zusammengefaßt. Dabei habe ich die Phasen, für welche die Diagramme im allgemeinen besonders gut geeignet sind, angegeben; im Einzelfall können sich Abweichungen hiervon ergeben.

Tabelle 1: Einsatzgebiete und Eigenschaften der verschiedenen Diagramme

Diagramm Phase Einsatzgebiet
Use-Case Anforderung,
Festlegung,
Erstellung,
Übergabe
Geschäftsprozesse, allgemeine Einsatzmöglichkeiten
Klassendiagramm Festlegung,
Erstellung
So gut wie überall, das Klassendiagramm ist das wichtigste Diagramm der UML.
Interaktionsdiagramm Anforderung,
Festlegung,
Erstellung,
Übergabe
Zeigt den Nachrichtenfluß und damit die Zusammenarbeit der Objekte im zeitlichen Ablauf.
Zeitliche Aufrufstruktur mit wenigen Klassen
Zeitliche Aufrufstruktur mit wenigen Nachrichten
Package-Diagramm Erstellung Groborientierung, in welchem Modul welche Klasse zu finden ist. Aufteilung in Unterprojekte, Bibliotheken, Übersetzungseinheiten.
Zustandsdiagramm Anforderung,
Festlegung,
Erstellung,
Übergabe
Darstellung des dynamischen Verhaltens.
Aktivitätsdiagramm Festlegung,
Erstellung
Bei parallelen Prozessen und anderer Parallelität, Geschäftsprozesse.
Implementierungsdiagramm Festlegung,
Erstellung,
Übergabe
Besonders für die Darstellung von verteilten Anwendungen und Komponenten; allgemein: Darstellung von Implementierungsaspekten (Übersetungseinheiten, ausführbare Programme, Hardwarestruktur)
Zusammenhänge der Software
Hardwareaufbau


Im folgenden beschreibe ich die verschiedenen Diagramme und gebe aus meiner Sicht Hinweise, Kommentare und Anregungen über das Einsatzgebiet. Wo es mir angebracht erscheint, habe ich mit Kritik nicht zurückgehalten. Einzelne Eigenschaften und Elemente werden als Durchbruch in der Geschichte der Softwareentwicklung angepriesen, sind aber Insidern längst bekannt.

Use-Case

Soviel gibt es über die Use-Cases gar nicht zu erzählen - sie sind schnell erklärt, aber ungemein nützlich. Die Use-Cases wurden von I. Jacobson eingeführt (vgl. [Jac92]). Sie beschreiben das Zusammenwirken von Personen mit einem System. Personen werden als Aktoren bezeichnet. Die Beschränkung der Aktoren auf Menschen kann verallgemeinernd auch aufgehoben werden, und die Aktoren können damit auch andere Systeme sein.

Handelt es sich bei den Aktoren um Personen, so müssen diese nach ihrem Rollenverhalten im Bezug auf das System und nicht nach den Menschen unterschieden werden. Ein Beispiel zeigt Abbildung 2: Hier kann z. B. der Bankangestellte auch selber ein Anleger sein.

Abb 2: Use-Case "Geld anlegen"


Unter einem Use-Case wird eine typische Handlung verstanden, die ein Benutzer mit dem System ausführt, z. B. "Aktienkauf". In das Use-Case-Diagramm werden die Use-Cases als Ellipsen eingezeichnet. Use-Cases können beliebig kompliziert und umfangreich sein. Verbindungen zwischen den Use-Cases und den Aktoren werden durch Linien hergestellt. Damit wird angezeigt, welche Aktoren an dem entsprechenden Use-Case beteiligt sind.

Im Use-Case-Diagramm gibt es zwei weitere Verbindungstypen: <<uses>> und <<extends>>.

Der Verbindungstyp <<uses>> wird verwendet, wenn zwei oder mehr Use-Cases einen ähnlichen Aufbau haben und Verhalten durch Kopieren wiederholt dargestellt werden muß. Dadurch ist es möglich, Verhalten von den Use-Cases in einen separaten Use-Case zu verlagern, und <<uses>>- Verbindungen zu den entsprechenden Use-Cases zu zeichnen. In Abbildung 2 ist dies bei Anlage und Festgeld der Fall.

Der Verbindungstyp <<extends>> klammert auch Verhalten aus, jedoch ist die Zielsetzung eine andere. Bei <<extends>> wird das Verhalten erweitert. Dies ist beispielsweise bei AuftragDrucken der Fall. AuftragDrucken stellt dem Use-Case Anlage zusätzliche Funktionalität zur Verfügung - hier z. B. das Drucken eines Auftrags (beachten Sie dabei bitte die Pfeilrichtung).

Klassendiagramm

Klassendiagramme sind der zentrale Bestandteil der UML und auch zahlreicher objektorientierter Methoden. Wie die Klassen ermittelt werden, darüber gibt die UML keine Auskunft; hierfür gibt es andere Techniken, z. B. CRC-Karten (Abk. für "Class, Responsibility and Collaboration") oder die Substantiv-Technik (vgl. [Rum91]). Die UML beschreibt lediglich die Notation und die Semantik:

Die strenge visuelle Unterscheidung zwischen Objekten und Klassen entfällt in der UML. Objekte werden von den Klassen dadurch unterschieden, daß ihre Bezeichnung unterstrichen ist, sonst sind die Symbole gleich. Auch können Klassen und Objekte zusammen im Klassendiagramm auftreten.

Elemente und Darstellung des Klassendiagramms

Das Klassendiagramm beschreibt die statische Struktur der Objekte in einem System sowie ihre Beziehungen untereinander. Abbildung 3 soll diesen Sachverhalt anhand eines Beispiels für ein gesamtes Klassendiagramm verdeutlichen. Das Bild zeigt ein - zugegebenermaßen stark vereinfachtes - Klassendiagramm einer Bank mit einer automatischen Geldausgabe an einem Geldautomaten.

Abb 3: Klassendiagramm "automatische Geldausgabe"


Die Klasse ist das zentrale Element; sie wird als Rechteck dargestellt (z. B. Geldautomat). Die gefundenen Klassen werden durch Linien miteinander verbunden. Diese Linien stellen die Elemente Assoziation, Aggregation, Komposition und Vererbung dar. Die Assoziation stellt eine allgemeine Beziehung zwischen zwei Klassen dar - über die Realisierung wird dabei nichts ausgesagt. Eine besondere Assoziation ist die Aggregation, die durch eine Raute an der Linie dargestellt wird (z. B. zwischen Kartenleser und Geldautomat). Sie gibt an, daß eine Klasse Kartenleser in der Klasse Geldautomat "enthalten" ist (Ist-Teil-von-Beziehung). An einer Assoziation können noch Multiplizitäten, d. h. Zahlen oder Zahlbereiche, angegeben werden. Diese bestimmen die Anzahl der Objekte, die miteinander in Beziehung stehen. Beispielsweise ist an einem Geldautomat genau ein UserInterface vorhanden. Die Komposition ist eine stärkere Form der Aggregation, die durch eine ausgefüllte Raute dargestellt wird (siehe Tresor). Bei der Beziehung Komposition handelt es sich um ein physikalisches Enthaltensein. In C++ können Aggregation und Komposition wie folgt realisiert werden:

class Geldautomat
{

}

Jede Assoziation kann eine Richtung besitzen; hierfür wird ein Pfeil am Ende der Assoziation angebracht. Zugriffe können dann nur in Pfeilrichtung erfolgen. Man verwendet deshalb den Begriff der Navigationsfähigkeit (engl. Navigability). Eine Assoziation mit Pfeil kann als Zeiger in einer Programmiersprache betrachtet werden.

Die Vererbung stellt eine Verallgemeinerung von Eigenschaften dar - sie wird auch als Spezialisierung und Generalisierung oder "Ist-ein"-Beziehung bezeichnet. Z. B. ist ein Auto ein Fahrzeug. Ein Fahrzeug hat generelle Eigenschaften eines Autos, und ein Auto spezialisiert die Eigenschaften von Fahrzeugen.

Die wichtigsten Elemente eines Klassendiagramms sind nochmals in Abbildung 4 dargestellt. Elemente für eine erweiterte Modellierung finden sich in [Rat97]. In Abbildung 4 sind für die Vererbung zwei gleichwertige Schreibweisen angegeben.

Abb 4: Elemente eines Klassendiagramms


Ausführlicher betrachtet hat eine Klasse den in Abbildung 5 gezeigten Aufbau - nun können Sie das Beispiel aus Abbildung 3 etwas besser verstehen:

Der Tresor hat einen Anfangsbestand von 1.000.000.

Abb 5: Aufbau einer Klasse: Beispiel und allgemeiner Aufbau


Eine Klasse besteht aus Attributen und Methoden. Attribute stellen die Eigenschaften der Objekte einer Klasse dar und bilden den Datenbestand der Klasse. Was mit diesen Daten getan werden kann, legen die Methoden fest. Methoden sind die aus anderen Sprachen bekannten Funktionen.

Wer auf die Daten zugreifen kann, wird durch die Sichtbarkeit der Daten bestimmt. Sichtbarkeiten können frühestens nach der Festlegungsphase eingeführt werden. private bedeutet, daß nur die Methoden dieser Klasse Zugriff haben, und protected heißt, daß auch Objekte der abgeleiteten Klassen Zugriff haben. public besagt, daß ein Zugriff jederzeit möglich ist. Die Sichtbarkeit kann sowohl für Attribute, als auch für Methoden angegeben werden.

Interaktionsdiagramm

Es gibt zwei Arten von Interaktionsdiagrammen:

Beide beschreiben die zeitlichen Abläufe, d. h. Aufrufsequenzen.

Ausgehend von Fallbeispielen - den Szenarios - können Interaktionsdiagramme erstellt werden. Deshalb werden die Interaktionsdiagramme auch Szenariodiagramme genannt. Beim Erstellen der Diagramme konzentriert man sich auf die "wichtigsten" Fälle (primäre Szenarios). Anschließend werden die Sonderfälle mit einbezogen und eventuell weitere Diagramme erstellt (sekundäre Szenarios).

Bei meiner täglichen Arbeit sind die Interaktionsdiagramme - noch vor den Klassendiagrammen - die für mich wichtigsten Diagramme. Sie werden häufig erstellt und dienen sowohl als Diskussionsgrundlage, als auch als Grundlage für die Implementierung und Dokumentation.

Sequenzdiagramme

Doch zunächst zu den Sequenzdiagrammen. Als Beispiel für die Erklärung der Interaktionsdiagramme soll die Adler-Apotheke dienen. In dieser Apotheke werden die Rezepte der Kranken in einen Computer eingegeben. Die Software ist wie folgt aufgebaut:

Eine Darstellung als Sequenzdiagramm zeigt Abbildung 6.

Abb 6: Sequenzdiagramm "Adler Apotheke"


Die Zeitachse verläuft von oben nach unten. Objekte sind als Rechtecke am oberen Ende von gestrichelten Linien - den "Lebenslinien" - dargestellt. Am linken Rand können noch Kommentare stehen. Zwischen den Lebenslinien wird der Austausch von Nachrichten durch Pfeile dargestellt. Eine Nachricht kann an eine Bedingung geknüpft sein, die in eckigen Klammern angegeben wird. Optional können noch Rücksprünge eingetragen werden - im allgemeinen verschlechtern diese aber die Lesbarkeit des Diagramms. Einige andere Details des Diagramms, wie etwa die Erzeugung von Objekten und die Iteration, erklären sich von selbst. Überhaupt wurde bei der UML viel Wert auf einfache Verständlichkeit gelegt.

Die Sequenzdiagramme wurden - um ihre Aussagekraft zu erhöhen - um einige nützliche Notationselemente erweitert; das Ergebnis ist in Abbildung 7 dargestellt.

Abb 7: Sequenzdiagramm mit Focus-of-Control, Erzeugen/Löschen und Bedingungen


Der Focus-of-Control (das langezogene Rechteck) gibt an, wo eine Aktivität ausgeführt wird. Ist ein Objekt ohne Aktivität vorhanden, wird dies durch eine gestrichelte Linie angezeigt. Objekte werden durch einen Pfeil auf das Rechteck erzeugt, ein Löschen wird durch ein Kreuz dargestellt. Über den Pfeilen stehen die Operationen, die ausgeführt werden. In eckigen Klammern können Bedingungen angegeben werden, wann die Operation ausgeführt wird. Ruft das Objekt eine Operation von sich selbst auf, etwa nachbestellungErforderlich(), dann zeigt der Pfeil auf die Lebenslinie zurück. Zusätzlich können am linken Rand noch Bemerkungen zu den einzelnen Operationen angegeben werden. Version 1.1 der UML bietet bei Bedarf noch einige weitere, feinere Notationselemente.

Kollaborationsdiagramm

Das Kollaborationsdiagramm und das Sequenzdiagramm beinhalten die gleichen Informationen und unterscheiden sich lediglich in der Darstellung. Die automatische Umwandlung eines Sequenzdiagramms in ein Kollaborationsdiagramm und umgekehrt ist möglich. Bei vielen Klassen und wenigen Nachrichten sind Kollaborationsdiagramme übersichtlicher als Sequenzdiagramme sind. Sind wenige Klassen und viele Nachrichten vorhanden, so ist das Sequenzdiagramm besser geeignet.

Ausgehend von unserem Beispiel, der Adler-Apotheke, ergibt sich für das vorher vorgestellte Beispiel der Bearbeitung von Rezepten das Kollaborationsdiagramm nach Abbildung 8.

Abb 8: Kollobarationsdiagramm für "Adler Apotheken Rezepte"


Das Kollaborationsdiagramm ist nicht nur ein wichtiges Hilfsmittel beim Entwurf und der Analyse, es hat mir auch schon oft bei der Fehlersuche geholfen. Während der Fehlersuche zeichne ich ein Kollaborationsdiagramm - damit läßt sich die Aufrufstruktur und das Zustandekommen eines Fehlers gut verfolgen.

Zustandsdiagramm

Aus den Interaktionsdiagrammen können Zustandsdiagramme entwickelt werden. Alle Szenarios definieren ein bestimmtes Zustandsdiagramm genauer. Die Szenarios sind so zu wählen, daß das Zustandsdiagramm einer Klasse vollständig definiert wird.

Theoretisch kann das Verhalten jeder Klasse durch ein Zustandsdiagramm beschrieben werden. In der Praxis ist das etwas einfacher. Nur für Klassen mit interessantem Verhalten werden Zustandsdiagramme angefertigt. Zustandsdiagramme sind nicht erforderlich für Klassen, die nur als Schnittstelle dienen und das Verhalten weiter delegieren. Das gleiche gilt für Klassen, die nur Werte zwischenspeichern.

Ein interessantes Verhalten weisen unter anderem all diejenigen Klassen auf, deren reale Objekte in der Umgangssprache mit "Automat" bezeichnet werden, wie z. B. Geldautomaten, Getränkeautomaten, automatische Aufzüge oder automatische Garagenöffner. Aus meiner täglichen Praxis kenne ich noch weitere Klassen mit interessantem Verhalten - Beispiele sind Klassen, die Übertragungsprotokolle realisieren, sowie Klassen, die Benutzeraktionen abarbeiten (z. B. Kennworteingabe).

Im folgenden soll das Beispiel eines Getränkeautomaten, aus dem verschiedene Getränke entnommen werden können, behandelt werden (der Automat ist in Abbildung 9 wiedergegeben).

Abb 9: Zustandsdiagramm für einen Getränkeautomaten


Rechtecke mit abgerundeten Ecken stellen die Zustände dar; zwischen jedem Nachrichtenaustausch im Sequenzdiagramm eines Objekts kann ein Zustand liegen. Durch das Eintreffen von Ereignissen kann ein anderer Zustand erreicht werden, was durch die Pfeile angedeutet wird, die eine Beschriftung für das auslösende Ereignis haben. Die Pfeile stellen die Übergänge dar. In den Zuständen werden Operationen mit einer gewissen Zeitdauer ausgeführt, die Aktivitäten genannt werden. Im Gegensatz dazu wird die Zeitdauer von Aktionen mit Null angenommen. Aktionen sind Operationen, die an den Übergängen ausgeführt werden. Angezeigt werden die Aktionen durch einen Schrägstrich vor dem Namen. Selbstverständlich können Übergänge auch an Bedingungen, die wieder in eckigen Klammern stehen, geknüpft werden.

Aus meiner Sicht (und auch nach [You96]) ist die Unterscheidung zwischen Aktivitäten und Aktionen akademisch. Jede reale Operation hat eine Zeitdauer - ob diese für eine Aufgabe relevant ist, hängt vom Einzelfall und nicht von der Darstellung in einem Diagramm ab. Den allgemeinen Aufbau eines Zustandsdiagramms zeigt Abbildung 10.

Abb 10: Zustandsdiagramm Symbole


Die Wörter entry, do und exit sind reserviert und können als Bezeichnungen für Ereignisse nicht verwendet werden. entry gibt an, welche Aktion beim Eintritt in einen Zustand ausgeführt wird. Ähnlich bezeichnet exit die Aktion, die beim Verlassen des Zustandes ausgeführt wird. Und schließlich beschreibt do den Aufruf eines verschachtelten Zustandsdiagramms. Allgemein bezeichnet do eine andauernde Aktivität, die unendlich lange andauern kann.

Erweiterungen auf parallele Verarbeitung, Oberzustände usw. sind möglich und können in der Literatur unter "parallele Zustandsdiagramme" (z. B. [Fow97], [Rat97], [Rum91]) nachgelesen werden. Falls Sie nicht sehr spezielle Probleme behandeln, reichen die hier vorgestellten Elemente für das Zustandsdiagramm bei weitem aus. Theoretisch ist ein Zustandsdiagramm auf eine Klasse bezogen. Wesentlich bedeutender finde ich es, dieses Konzept auch während der Analyse - unabhängig von speziellen Klassen - zu haben. Dann kann auf ein Blatt Papier ein Zustandsdiagramm, das sich nicht auf eine spezielle Klasse bezieht, gezeichnet und diskutiert werden. Später lassen sich daraus bei Bedarf Zustandsdiagramme für spezielle Klassen ableiten.

Zustandsdiagramme für die Formatprüfung von Benutzereingaben, z. B. die Uhrzeit, können sehr gut direkt gezeichnet werden. Aber auch Übertragungsprotokolle werden häufig über Zustandsdiagramme definiert. Nicht immer läßt sich ein Zustandsdiagramm direkt zeichnen, dann sind vorher geeignete Szenarios und gegebenenfalls Interaktionsdiagramme zu erstellen.

Package-Diagramm

Package-Diagramme dienen der Strukturierung der verschiedenen Darstellungen. Damit werden Gruppen von Diagrammen oder Elementen zusammengefaßt. Dies ist insbesondere wichtig für den Überblick über das System und die Aufteilung in verschiedene Übersetzungseinheiten. Ein Beispiel ist in Abbildung 11 zu sehen.

Abb 11: Beispiel für ein Package-Diagramm


Ein Package-Diagramm besteht im wesentlichen aus Packages (dargestellt durch große Rechtecke mit kleinem Rechteck links oben) und Abhängigkeiten (den gestrichelten Pfeilen). Eine Abhängigkeit gibt an, daß bei einer Änderung des Packages an der Pfeilspitze das Package am anderen Ende der gestrichelten Linie eventuell geändert bzw. neu übersetzt werden muß. Ob eine Änderung bzw. Neuübersetzung erforderlich ist, muß im Einzelfall geprüft werden. Packages, die nicht durch eine Abhängigkeit verbunden sind, können bei der Änderung außer acht gelassen werden. Packages können weitere Packages enthalten.

Packages geben zum einen einen guten Überblick über die Auswirkung von Änderungen und ermöglichen zum anderen einen Überblick über das Gesamtsystem. Insbesondere für größere Systeme ist eine solche Strukturierung wichtig.

In Abbildung 11 muß die Applikation Textverarbeitung auf Änderungen überprüft werden, wenn sich das Package Datei I/O, UI oder Rechtschreibung ändert. Das Package UI soll hier eine abstrakte Klasse darstellen, die lediglich als Schnittstelle dient. Damit ist es möglich, daß Änderungen in den Packages Windows und OS/2 keine Auswirkungen auf das Package Textverarbeitung haben. Aus diesem Grund ist hier eine Generalisierung eingezeichnet (vgl. Klassendiagramme).

Aktivitätsdiagramm

Aktivitätsdiagramme sind ganz neu; sie stellen eine Mischung verschiedener, bekannter Darstellungstechniken dar. Grundlage waren unter anderem Zustandsdiagramme, Flußdiagramme und Petrinetze. Da Aktivitätsdiagramme noch neu sind, liegen auch noch keine umfangreichen Erfahrungen vor. Ihre weitere Entwicklung und Bedeutung wird sich erst erweisen, sonst werden sie das gleiche Schicksal wie die Petrinetze erleiden - bekannt, theoretisch untersucht, in der Praxis aber selten verwendet.

Petrinetze sind ihrem Wesen nach für parallele Prozesse und die Modellierung von Arbeitsabläufen (Workflow-Modellierung) geeignet, allerdings nur, solange die Problemstellung nicht zu komplex wird oder sich die Problemstellung reduzieren läßt. Umfangreiche Zusammenhänge sind mit Petrinetzen nur schwer darstellbar. Für die Aktivitätsdiagramme gilt das gleiche.

Ich möchte die Aktivitätsdiagramme deshalb nicht überbetonen und hier nur eine kurze Darstellung geben. Grundelemente dieser Diagrammart sind:

Aktivitäten sind Zustände, in denen Vorgänge ablaufen. Transitionen erfolgen automatisch am Ende der Aktivitäten; sie werden durch Pfeile dargestellt. Synchronisationslinien werden durch Striche dargestellt und schalten, wenn alle Eingangstransitionen vorhanden sind. "Swimlanes" teilen ein Aktivitätsdiagramm so ein, daß die Bereiche, die sie abgrenzen, einzelnen Klassen zugeordnet werden können.

Ein Beispiel für ein Aktivitätsdiagramm zeigt Abbildung 12. Zusätzlich können noch Bedingungen eingeführt werden, welche die Transitionen näher bestimmen.

Abb 12: Beispiel für ein Aktivitätsdiagramm


Implementierungsdiagramm

Implementierungsdiagramme zeigen Aspekte der Implementierung. Diese umfassen die Codestruktur und die Struktur des Systems zur Ausführungszeit. Insbesondere für verteilte Anwendungen und Komponentensoftware ist das wichtig. Von den Implementierungsdiagrammen gibt es zwei Formen:

Komponentendiagramme zeigen die Struktur des Codes und Deployment-Diagramme die des Laufzeitsystems.

Mit zunehmender Bedeutung der verteilten Anwendungen und Komponentensoftware werden diese Diagramme an Bedeutung gewinnen. Bis jetzt habe ich für Projekte nur wenige Implementierungsdiagramme gezeichnet. Eine Ausnahme hiervon bilden Diagramme, die wichtige Übersetzungsabhängigkeiten zeigen.

Komponentendiagramm

Das Komponentendiagramm (siehe Abb. 13) zeigt die Abhängigkeiten unter den Softwarekomponenten, genauer die Abhängigkeiten zwischen Quellcode, Binärcodekomponenten und ausführbaren Programmen. Einige dieser Komponenten existieren nur während des Übersetzungsvorgangs, einige nur während des Linkens, andere zur Ausführungszeit und wieder andere die ganze Zeit über. Im Komponentendiagramm haben die Darstellungen nur Typencharakter, im Gegensatz zu den Deployment-Diagramm, wo sie zu Instanzen werden (d. h. die Bezeichnungen werden unterstrichen).

Abb 13: Beispiel für ein Komponentendiagramm


Die Komponenten werden als drei ineinander verschachtelte Rechtecke gezeichnet; ihre Schnittstellen sind Striche mit Kreisen am Ende. Dadurch können die verschiedenen Schnittstellen der Komponenten dargestellt werden. Das Diagramm enthält ferner Abhängigkeiten in Form von gestrichelten Pfeilen.

Sie werden sich fragen, wo der Unterschied zu den Package-Diagrammen liegt. Der Unterschied besteht darin, daß die Package-Diagramme ein allgemeines Mittel für die Strukturierung darstellen, während die Komponentendiagramme Implementierungsaspekte zeigen. In der Praxis entspricht eine Komponente einem Package, aber nicht jedes Package einer Komponente.

Die Abhängigkeiten eines Package-Diagramms, das in ein Komponentendiagramm umgewandelt werden kann, sind genau die gleichen wie die im Komponentendiagramm.

Deployment-Diagramme

Zur Darstellung der Hardware werden Deployment-Diagramme verwendet. Diese besitzen sogenannte Knoten, die eine Verarbeitungs- oder Hardwareeinheit darstellen. Knoten werden als Quader gezeichnet. Unter den Knoten existieren Verbindungen: Dabei handelt es sich um die physikalischen Kommunikationspfade, die als Linien eingezeichnet werden (ein Beispiel zeigt Abb. 14).

Abb 14: Beispiel für ein Deployment-Diagramm


In das Deployment-Diagramm können noch die Komponenten und ihre Abhängigkeiten eingezeichnet werden. Somit erhalten Sie einen Überblick, wo die Komponenten ausgeführt werden.

Stereotypen

Die Erklärung des Begriffes "Stereotyp" möchte ich nicht versäumen. Früher oder später werden Sie im Zusammenhang mit der UML auf diesen Begriff stoßen. Falls Sie dann nachfolgende Erklärung nicht mehr in Erinnerung haben, können Sie diese zumindest nachlesen.

Stereotypen sind Mechanismen, die es erlauben, die UML zu erweitern. Der Begriff wird nur selten ins Deutsche übersetzt, und überhaupt sind Erklärungen dafür recht selten, obwohl der Begriff "Stereotyp" häufig verwendet wird. Übersetzungen aus dem Lexikon ergeben Begriffe wie "Druckvorlage", "Muster", "Musterbeispiel", "Vorbild". Stereotypen haben in der UML die Bedeutung "so ähnlich etwa wie". Stereotypen können eigene Piktogramme (Icons) haben und werden in eckigen Klammern dargestellt, z. B. <<uses>>. Sie erlauben eine weitere Einteilung der Klassen, Abhängigkeiten, Assoziationen etc. So ist z. B. eine Einteilung der Klassen in Schnittstellen-, Kontroll- und Entitätenobjekte (irgendwelche Dinge) möglich.

Ausblick

In diesem Beitrag wurde auf die wesentlichen Merkmale und Beschreibungselemente der UML eingegangen. Auf eine nähere Erläuterung von Mustern, Schnittstellen, parametrisierten Klassen, Verfeinerungen und spezielle Details einiger Diagramme wurde verzichtet. Der fortgeschrittene Leser sei hierfür auf die einschlägige Literatur verwiesen.

Die "Unified Modeling Language" ist in Zukunft nicht mehr aus der OO-Welt wegzudiskutieren. Sie stellt den De-facto-Stand der Technik dar. Der Methodenkrieg ist damit beendet, obwohl es an einigen anderen Stellen weiterhin Glaubenskriege gibt - so wurde die Frage der Codegenerierung zu einem solchen erklärt. Auf diese Diskussion möchte ich mich nicht weiter einlassen, ich möchte jedoch zu bedenken geben, daß damit auch wirtschaftliche Interessen verbunden sind. Ich bin der Meinung, daß die Codegenerierung um jeden Preis als Zielsetzung zumindest bezweifelt werden kann.

Viel wichtiger ist, daß die Spezifikation der Software durch die mit der Aufgabe betrauten Fachbereiche eine vernünftige Form annimmt.Vage Vorgaben, Forderungen, die sich alle zwei Wochen grundsätzlich ändern, implizite Annahmen, die niemand, - außer einigen Fachleuten - kennt, sind häufig ein Grund für aufwendigen Zeitverlust bei Projekten und Ursache vieler weiterer Probleme. Auch hier sehe ich ein großes Potential für den Einsatz der UML. Warum beschäftigen sich eigentlich vorwiegend die Softwareingenieure mit Softwareentwicklungsmethoden? Warum nicht auch die Fachbereiche? Die UML könnte auch Bestandteil der Ausbildung von betriebswirtschaftlichen Berufen, die später Schnittstellen zu Dienstleistern aus der Datenverarbeitung haben, sein, etwa als Bestandteil eines Betriebwirtschaftsstudiums.

Ein Artikel über die UML wäre unvollständig, ginge er nicht zumindest am Rande auf Werkzeuge, die die UML unterstützen, ein. Seit dem Erscheinen der UML gehen praktisch alle Werkzeughersteller in Richtung UML. Kein Anbieter kann und wird es sich auf Dauer leisten können, die UML nicht zu unterstützen. Die Anzahl der Werkzeuge steigt fast täglich. Hier eine konkrete Empfehlung zu geben ist schwierig. Zweifellos versucht die Firma Rational den Markt zu dominieren, und ihr Werkzeug Rose ist - trotz aller Schwächen - brauchbar.

Allerdings sollte man sich zunächst über die Zielsetzung im klaren sein, die mit dem Einsatz der UML verfolgt werden soll. Ist das Ziel ein konsistentes Modell oder die Erzeugung von Code, so kann dies nur mit einem Werkzeug erreicht werden. Besteht die Zielsetzung mehr in der Spezifikation oder Dokumentation von Software, kann auch der Einsatz einfacher Zeichenprogramme sehr wertvoll sein. Falls ein PC zur Verfügung steht, würde ich die Verwendung von Microsoft Word und Visio empfehlen. Damit lassen sich hervorragende Dokumente erstellen.

Menschen, die sich ernsthaft mit der Entwicklung von Software auseinandersetzen, werden in Zukunft nicht an der UML vorbeikommen. Ich hoffe, damit einen Beitrag geleistet zu haben und wünsche Ihnen mit der UML viel Erfolg .

Literatur

[Boo94] G. Booch, Object-oriented Analysis and Design with Applikations, 1994 Benjamin/Cummings Publishing Company, 1994

[Fow97] M. Fowler, UML Distilled, Applying the Standard Object Modeling Language, 2nd Printing, Addison-Wesley, 1997

[Jac92] I. Jacobson, Object-Oriented Software Engineering, A Use Case driven Approach, Addison-Wesley 1992

[Rat97] UML Unified Modeling Language, Version 1.0 und 1.1 (siehe: http://www.rational.com)

[Rum91] J. Rumbaugh, Objektorientiertes Modellieren und Entwerfen, Hanser Verlag 1993 (Titel der amerikanischen Ausgabe: Object-Oriented Modeling and Desing, Prentice Hall, 1991).

[You96] E. Yourdon et. al, Mainstream Objects, Prentice Hall, 1996

Dipl. Inform. Günter Wahl (E-Mail-Adresse: GWahl@t-online.de) ist Softwareingenieur bei der Firma Robert Bosch, wo er bereits zahlreiche Projekte betreut und realisiert hat. Sein Schwerpunkt liegt auf dem Gebiet der objektorientierten Methoden und Programmierung.