Strukturdiagramm
Klassendiagramm
Welche Klassen gibt es und wie hängen sie zusammen?
Eine Aufgabe beschreibt in Prosa, welche Dinge es in einem System gibt und wie sie zusammenhängen, zum Beispiel Kunden, Bestellungen und Bestellpositionen. Das Klassendiagramm hält diese statische Struktur fest: Klassen mit ihren Attributen und Operationen und die Beziehungen zwischen ihren Objekten. In der IHK-Abschlussprüfung ist es die häufigste Diagrammart und zugleich die Vorlage für Datenmodell und Code.
Beziehungen im Vergleich.
Durchgezogene Linie mit Multiplizitäten an den Enden.
Eine Bestellung muss dauerhaft wissen, zu welchem Kunden sie gehört. Genau diese Verbindung zwischen Objekten hält die Assoziation als durchgezogene Linie fest. An jedes Ende schreibst du eine Multiplizität, also die Anzahl der Objekte, die dort beteiligt sein dürfen. Gelesen wird sie vom gegenüberliegenden Ende aus: Ein Kunde gibt 0..* Bestellungen auf, deshalb steht 0..* an der Bestellung. Ein Name auf der Linie sagt, worin die Verbindung besteht (UML 2.5.1, Kapitel 11).
Hohle Raute an der Klasse, die das Ganze ist.
In diesem Modell bleibt ein Mitarbeiter erhalten, wenn sein Team aufgelöst wird, und darf mehreren Teams angehören. Wir stellen diese Teil-Ganzes-Beziehung als geteilte Aggregation mit hohler Raute am Team dar. Die 0..* am Team-Ende erlaubt mehrere Teams. UML 2.5.1 legt die Notation fest, lässt die genaue Bedeutung der geteilten Aggregation aber dem Modell: Die Raute allein garantiert weder Mehrfachzugehörigkeit noch bestimmte Löschregeln (Abschnitt 9.5.3 und 11.5.4).
Gefüllte Raute an der Klasse, die das Ganze ist.
Eine Bestellposition gehört in diesem Modell fest zu ihrer Bestellung. Diese starke Teil-Ganzes-Beziehung zeichnest du mit einer gefüllten Raute am Ganzen. Ein Teil gehört gleichzeitig zu höchstens einem Ganzen, deshalb steht am Rautenende 1 oder 0..1. Wird das Ganze gelöscht, werden seine noch zugehörigen Teile mitgelöscht. Falls das Modell es erlaubt, kann ein Teil vorher gelöst oder umgehängt werden. Eine gleichzeitige Erzeugung von Ganzem und Teil verlangt UML nicht (UML 2.5.1, Abschnitt 9.5.3).
Durchgezogene Linie mit hohlem Dreieck an der Oberklasse.
Ein Geschäftskunde hat alles, was ein Kunde hat, dazu eine Firma und eine Umsatzsteuer-ID. Statt beides doppelt aufzuschreiben, verbindest du die Klassen mit einer Generalisierung: Die Unterklasse erbt Attribute und Operationen der Oberklasse. Die Linie läuft vom Speziellen zum Allgemeinen, das hohle Dreieck sitzt an der Oberklasse. Multiplizitäten gibt es hier nicht, weil nicht Objekte verbunden werden, sondern Klassen (UML 2.5.1, Kapitel 9).
Gestrichelte Linie mit hohlem Dreieck am Interface.
Ein Interface legt fest, welche Operationen es gibt, aber nicht, wie sie arbeiten. Wenn eine Klasse diesen Vertrag erfüllt, verbindest du beide mit einer Realisierung: gestrichelte Linie, hohles Dreieck am Interface. Leserichtung und Dreieck sind dieselben wie bei der Generalisierung, nur die Linie ist gestrichelt. Die Klasse muss dann jede Operation des Interfaces anbieten (UML 2.5.1, Kapitel 7).
Gestrichelte Linie mit offener Pfeilspitze zum Benutzten.
Ein ReportService benötigt PdfExport für seine Implementierung, etwa als Parametertyp. Diese Abhängigkeit zeichnest du als gestrichelte Linie mit offener Pfeilspitze zur benötigten Klasse. Ändert sich PdfExport, kann das eine Änderung am ReportService erfordern. Die Beziehung beschreibt eine Abhängigkeit zwischen Modellelementen und trägt keine Multiplizitäten. Sie legt weder eine kurze Nutzungsdauer noch ein Verbot gespeicherter Referenzen fest (UML 2.5.1, Kapitel 7).
Symbole und Notation.
13 Elemente
Klasse
Rechteck mit drei Kompartimenten
Oben der Klassenname, in der Mitte die Attribute, unten die Operationen. Diese drei Kompartimente sind die Fächer des Rechtecks. Du darfst Attribute und Operationen ausblenden, auch wenn sie im Modell existieren. Ein großgeschriebener Name im Singular ist eine Namenskonvention, keine UML-Pflicht (UML 2.5.1, Kapitel 9).
Abstrakte Klasse
Name kursiv oder {abstract}
Von einer abstrakten Klasse gibt es keine Objekte, sie sammelt nur Gemeinsamkeiten für ihre Unterklassen. Objekte entstehen erst aus den konkreten Unterklassen. Du erkennst sie am kursiven Namen, von Hand schreibst du stattdessen {abstract} dazu.
Interface
«interface» über dem Namen
Ein Interface beschreibt einen Vertrag: welche Operationen es gibt, ohne festzulegen, wie sie arbeiten. Über dem Namen steht das Schlüsselwort «interface». Klassen erfüllen diesen Vertrag über eine Realisierung.
Sichtbarkeit
+ - # ~
Das Zeichen vor jedem Attribut und jeder Operation sagt, wer darauf zugreifen darf: + public für alle, - private nur innerhalb der Klasse, # protected zusätzlich für Unterklassen, ~ package innerhalb desselben Pakets. Attribute stehen meistens auf privat, die Operationen, mit denen andere Klassen arbeiten sollen, auf öffentlich.
Attribut
sichtbarkeit name : Typ [Mult] = Wert
Ein Attribut beschreibt einen Wert eines Objekts. Der Typ steht hinter dem Doppelpunkt, eine Multiplizität in eckigen Klammern zeigt, wie viele Werte erlaubt sind, und nach dem Gleichheitszeichen folgt ein Standardwert. Sichtbarkeit, Typ, Multiplizität und Standardwert dürfen in der Darstellung entfallen.
Operation
sichtbarkeit name(param : Typ) : Rückgabe
Eine Operation ist etwas, das ein Objekt tun kann. In den Klammern stehen die Parameter mit Namen und Typ, hinter dem schließenden Doppelpunkt der Rückgabetyp. Die Klammern gehören auch dann dazu, wenn es keine Parameter gibt, denn sonst sieht die Zeile aus wie ein Attribut.
Assoziation
Durchgezogene Linie
Eine durchgezogene Linie beschreibt mögliche Verbindungen zwischen Objekten beider Klassen. Sie legt keine Mindestdauer dieser Verbindungen fest. Die Multiplizität steht an dem Ende, für das sie gilt, gelesen wird sie vom gegenüberliegenden Ende aus. Ein Name auf der Linie sagt, worin die Verbindung besteht.
Aggregation
Hohle Raute am Ganzen
Die hohle Raute sitzt an der Klasse, die das Ganze ist, und kennzeichnet eine geteilte Aggregation. UML lässt deren genaue Bedeutung dem Modell. Hier bleiben Mitarbeiter bei Auflösung eines Teams erhalten; die Multiplizität 0..* erlaubt mehrere Teams. Diese Regeln folgen nicht allein aus der Raute.
Komposition
Gefüllte Raute am Ganzen
Die gefüllte Raute sitzt am Ganzen. Ein Teil gehört gleichzeitig zu höchstens einem Ganzen, deshalb steht am Rautenende 1 oder 0..1. Wird das Ganze gelöscht, werden seine noch zugehörigen Teile mitgelöscht. Wenn das Modell es erlaubt, kann ein Teil vorher gelöst oder umgehängt werden.
Generalisierung
Hohles Dreieck an der Oberklasse
Die Unterklasse erbt Attribute und Operationen der Oberklasse und ergänzt eigene. Die Linie läuft vom Speziellen zum Allgemeinen, das hohle Dreieck sitzt an der Oberklasse. Multiplizitäten stehen hier nicht, weil Klassen verbunden werden und keine Objekte.
Realisierung
Gestrichelt mit hohlem Dreieck
Die Klasse erfüllt den Vertrag des Interfaces und bietet alle dort genannten Operationen an. Gezeichnet wird das wie eine Generalisierung, nur mit gestrichelter Linie; das hohle Dreieck zeigt zum Interface.
Abhängigkeit
Gestrichelt mit offener Spitze
Eine Klasse benötigt eine andere für ihre Definition oder Implementierung, etwa als Parametertyp. Die offene Pfeilspitze zeigt auf die benötigte Klasse. Eine Änderung dort kann die abhängige Klasse betreffen. Die Linie sagt nichts über die Nutzungsdauer aus und trägt keine Multiplizitäten.
Multiplizität
1 0..1 * 1..* 0..*
Die Multiplizität sagt, wie viele Objekte an diesem Ende beteiligt sein dürfen: 1 genau eines, 0..1 höchstens eines, 1..* mindestens eines, 0..* oder * beliebig viele. Auch feste Bereiche wie 5..30 sind erlaubt. Gelesen wird immer vom gegenüberliegenden Ende aus.
So liest und zeichnest du ein Klassendiagramm.
Wozu das Diagramm da ist
In der Prüfung bekommst du einen Text: Kunden geben Bestellungen auf, jede Bestellung besteht aus Positionen, Geschäftskunden haben zusätzlich eine Umsatzsteuer-ID. Gefragt ist nicht der Ablauf, sondern die Struktur dahinter. Das Klassendiagramm zeigt genau diese statische Struktur: welche Klassen es gibt, welche Daten und Fähigkeiten sie haben und wie ihre Objekte miteinander verbunden sind.
Eine Klasse ist die Beschreibung einer Sorte von Dingen, ein Objekt ein einzelnes Exemplar davon. Kunde ist die Klasse, die Kundin mit der Nummer 4711 ist ein Objekt. Das Diagramm beschreibt immer die Klassen, die Multiplizitäten sagen dann etwas über die Objekte.
Woher die Notation kommt
UML wird von der Object Management Group (OMG) standardisiert, einem Konsortium, das technische Spezifikationen pflegt. Grundlage ist UML 2.5.1. Attribute, Operationen, Generalisierung und Aggregationssemantik stehen dort in Kapitel 9, Klassen, Interfaces und Assoziationsnotation in Kapitel 11, Abhängigkeit und Realisierung in Kapitel 7.
Die Spezifikation legt fest, welches Symbol was bedeutet: gefüllte Raute, hohles Dreieck, gestrichelte Linie. Sie schreibt nicht vor, wie du das Diagramm anordnest, welche Farben du nimmst oder mit welchem Werkzeug du zeichnest. Ein Diagramm auf Papier ist genauso gültig wie eines aus einem Modellierungswerkzeug.
So liest du es
Fang bei einer Klasse an. Im obersten Kompartiment, also im obersten Fach des Rechtecks, steht der Name, darunter die Attribute, unten die Operationen. Das Zeichen am Zeilenanfang ist die Sichtbarkeit: + öffentlich, - nur innerhalb der Klasse, # zusätzlich für Unterklassen, ~ innerhalb des Pakets. Klammern am Ende einer Zeile zeigen, dass es sich um eine Operation handelt und nicht um ein Attribut.
Folge dann den Linien nach außen. Multiplizitäten liest du vom gegenüberliegenden Ende aus, und genau das erwartet die IHK-Prüfung: Steht am Ende bei Bestellung eine 0..*, dann gehören zu einem Kunden null bis beliebig viele Bestellungen. Steht am Ende bei Kunde eine 1, dann gehört jede Bestellung zu genau einem Kunden. In Worten wird daraus ein Satz pro Richtung: "Ein Kunde gibt 0..* Bestellungen auf" und "Eine Bestellung gehört zu 1 Kunden".
Achte zuletzt auf die Enden der Linien. Eine Raute steht immer an der Klasse, die das Ganze ist, hohl bei loser Zugehörigkeit nach den Regeln des Modells und gefüllt, wenn noch zugehörige Teile mit dem Ganzen gelöscht werden. Ein hohles Dreieck steht an der Oberklasse und bedeutet Vererbung, gestrichelt mit Dreieck heißt, dass eine Klasse ein Interface erfüllt. Eine gestrichelte Linie mit offener Spitze zeigt auf ein Element, das für die Definition oder Implementierung benötigt wird.
So zeichnest du es in der Prüfung
- 1 Unterstreiche im Aufgabentext die Substantive, über die etwas ausgesagt wird. Daraus werden deine Kandidaten für Klassen, jeweils im Singular und großgeschrieben.
- 2 Zeichne die Rechtecke locker verteilt auf das Blatt und lass Platz zwischen ihnen. Verwandte Klassen legst du nebeneinander, Ober- über Unterklassen. Die Linien brauchen später mehr Raum, als du denkst.
- 3 Trage die Attribute ein, in der Form Sichtbarkeit, Name, Doppelpunkt, Typ, also zum Beispiel - kundennr : Integer. Verweise auf andere Klassen kannst du auch als Assoziation darstellen. Zeichne dieselbe Eigenschaft nicht versehentlich doppelt.
- 4 Ergänze die Operationen, die die Aufgabe verlangt, mit Klammern und Rückgabetyp, zum Beispiel + gesamtpreis() : Decimal. Wenn nichts gefordert ist, lass das Fach lieber leer, als es zu erfinden.
- 5 Zeichne zuerst die Vererbung: Wo lässt sich ein Satz mit "ist ein" bilden, dort läuft die Linie vom Speziellen zum Allgemeinen, mit hohlem Dreieck an der Oberklasse. Verschiebe gemeinsame Attribute dabei nach oben.
- 6 Verbinde die restlichen Klassen mit durchgezogenen Linien. Verwende eine gefüllte Raute, wenn jedes Teil höchstens ein Ganzes hat und noch zugehörige Teile mit ihm gelöscht werden. Eine hohle Raute verwendet ihr für eine geteilte Aggregation nach den Regeln eures Modells. Sonst genügt eine Assoziation.
- 7 Schreibe zum Schluss an jedes Assoziationsende eine Multiplizität und lies jede Assoziation einmal laut in beide Richtungen. Was sich falsch anhört, steht meist am falschen Ende.
Prüfe dich selbst: Ein Kurs hat mehrere Noten, und wird der Kurs aus dem System entfernt, sind auch seine Noten gegenstandslos. Ein Lehrer dagegen bleibt im System, wenn sein Kurs endet. Welche der beiden Verbindungen zeichnest du mit gefüllter Raute, wo sitzt sie, und welche Multiplizität steht am Rautenende?
Typische Prüfungsfehler.
6 Paare
Die Raute sitzt am Teil statt am Ganzen.
Die Raute wird leicht mit einer Pfeilspitze verwechselt und am Teil platziert. Sie markiert aber immer das Ganze. Eine Bestellung besteht in diesem Modell aus mindestens einer Position, also gehört die Raute an die Bestellung und die Position bekommt 1..*.
Das Dreieck zeigt zur Unterklasse.
Wer die Vererbung von oben nach unten denkt, zeichnet den Pfeil in Richtung der erbenden Klasse. Die Notation läuft umgekehrt: vom Speziellen zum Allgemeinen, mit dem hohlen Dreieck an der Oberklasse. Prüfe die Richtung mit einem Satz: Ein Geschäftskunde ist ein Kunde, also zeigt das Dreieck auf Kunde.
Multiplizitäten stehen am falschen Ende.
Die Zahl landet oft bei der Klasse, über die man gerade gesprochen hat: "Ein Kunde hat viele Bestellungen", also 0..* an den Kunden. Gelesen wird eine Multiplizität aber vom gegenüberliegenden Ende aus. Weil ein Kunde 0..* Bestellungen hat, steht 0..* an der Bestellung; weil eine Bestellung zu genau einem Kunden gehört, steht 1 am Kunden.
Java-Syntax statt UML-Syntax.
Wer viel programmiert, schreibt die Zeilen automatisch so hin, wie sie im Quelltext stehen. UML dreht die Reihenfolge um: erst der Name, dann hinter einem Doppelpunkt der Typ. Die Sichtbarkeit steht als Zeichen davor, nicht als Schlüsselwort.
Komposition, obwohl das Teil allein weiterlebt.
In diesem Modell darf ein Mitarbeiter gleichzeitig mehreren Teams angehören und bleibt beim Auflösen eines Teams erhalten. Das passt nicht zur Komposition: Ein Teil hat höchstens ein Ganzes und wird mitgelöscht, solange es noch dazugehört. Hier verwenden wir eine geteilte Aggregation mit hohler Raute; eine einfache Assoziation wäre ebenfalls möglich. Die genaue Bedeutung der geteilten Aggregation muss das Modell festlegen.
Operationen ohne Klammern.
Unter Zeitdruck fallen die leeren Klammern weg, weil sie nichts zu enthalten scheinen. Ohne sie ist die Zeile aber nicht mehr von einem Attribut zu unterscheiden, und das Kompartiment verliert seine Aussage. Schreibe die Klammern immer, auch wenn keine Parameter darin stehen.
Zwei vollständige Beispiele.
Bibliothek: Interface, abstrakte Klasse und alle Beziehungsarten in einem Bild.
Ein Medium steht hier für ein einzelnes ausleihbares Exemplar mit eigener Inventarnummer, nicht für alle Exemplare eines Titels. Medium ist abstrakt; Buch und DVD sind die gezeigten konkreten Unterklassen und erben seine Eigenschaften. Weitere Unterklassen sind möglich. Medium erfüllt den Vertrag Ausleihbar. Die Regale sind in diesem Modell verwaltete Datensätze der Bibliothek: Wird sie gelöscht, werden ihre noch zugehörigen Regaldatensätze mitgelöscht, die Medien bleiben erhalten. Die hohle Raute ordnet Medien einem Regal zu; die 0..1 erlaubt, dass ein ausgeliehenes Medium keinem Regal zugeordnet ist. Der Parametertyp Mahnservice begründet die Abhängigkeit des Nutzers.
Schule: eine Oberklasse, zwei Unterklassen und benannte Assoziationen.
Schüler und Lehrer teilen sich Name und Geburtsdatum, deshalb hängen beide über eine Generalisierung an der abstrakten Klasse Person. Die Namen auf den Linien ("belegt", "leitet", "erhält") sagen, worin die jeweilige Verbindung besteht. Am Schüler-Ende steht 5..30: Ein Kurs hat also 5 bis 30 Schüler. Multiplizitäten dürfen auch fachliche Bereiche angeben, nicht nur 1 oder *. Eine Note existiert in diesem Modell nur innerhalb ihres Kurses, deshalb hängt sie mit einer gefüllten Raute daran.
Zusätzliche Modellregel: Eine Note darf nur einem Schüler gehören, der ihren Kurs belegt. Diese Bedingung zwischen den drei Assoziationen folgt nicht aus den Multiplizitäten allein. Die Kursbelegung bleibt deshalb für benotete Schüler erhalten. Der Ausschnitt zeigt laufende Kurse mit 5 bis 30 Teilnehmern, noch keine leeren Kurse in Planung.