Software-Engineering (2): Softwareentwicklung mit UML

1 Allgemeines

Die Unified Modelling Language ist eine Modellierungssprache zur Spezifikation, Konstruktion und Dokumentation von verteilten Objekt Systemen.

UML setzt sich aus verschiedenen Bausteinen und insgesamt 14 Diagrammtypen zusammen, um statische Strukturen und dynamisches Verhalten visualisieren zu können.

1.1 grafische Darstellung

Die 14 UML Diagrammtypen lassen sich in zwei Gruppen unterteilen:

1.1.1 Statisches Modell (Strukturdiagramme)

Im statischen Modell werden die Elemente des Systems (Klassen, Objekte, Pakete, Komponenten) und deren Beziehungen modelliert

Strukturdiagramme lassen sich weiter in 7 Diagrammarten unterteilen:

1.1.2 Dynamisches Modell (Verhaltensdiagramme)

Mit den Diagrammen des dynamischen Modells wird das Verhalten der Elemente beschrieben. Es werden Anwendungsfälle, deren Auslöser, die einzelnen Aktivitäten, die Zusammenarbeit der Objekte-Zustände dargestellt.

auch die Verhaltensdiagramme teilen sich in 7 weitere Arten auf:

1.2 Gemeinsame Elemente aller Diagramme

1.2.1 Rahmen

UML Diagramme können mit einem Rahmen ausgestattet werden, in dessen linken oberen Ecke der Diagrammtyp, der Diagrammname und weitere Informationen platziert werden können.

Rahmen

Abkürzungen wie "uc" (Use Case) für das Anwendungsfalldiagramm oder "stm" (State Machine) für das Zustandsdiagramm werden oft als Typangabe verwendet.

1.2.2 Kommentar

Jedem anderen Element kann ein Kommentar zugeordnet werden. Dieser steht in einem Rechteck, dessen rechte obere Ecke "umgeknickt" dargestellt wird. Der Kommentar wird über eine gestrichelte Linie mit einem Element verbunden.

Kommentar

1.2.3 Randbedingung (Zusicherungen, Constraints)

In Kommentaren oder anderen Elementen können Randbedingungen (Boolescher Ausdruck) angegeben werden um auszudrücken, dass ein Sachverhalt nur in bestimmten Fällen gilt.
Ein Bedingungsausdruck wird in geschweifte Klammern gefasst. Am Klammernanfang kann ein Name für das Constraint angegeben werden.

Beispiele für Constraints
Constraints Erklärung
{or}, {xor}, {and} Drücken aus, ob bestimmte Zustände gleichzeitig gegeben sein müssen oder können
{ordered} Legt fest, dass eine Folge von Werten (z.B. die Elementen einer Liste) geordnet vorliegen müssen
{istStand > 500} Gibt an, dass das Attribut istStand einen Wert über 500 aufweisen muss
{Artikel muss existieren} Die Formulierung von Constraints kann sich an Programmiersprachen orientieren, aber auch natursprachlich erfolgen.

1.2.4 Stereotyp

Um wiederkehrende Zusammenhänge vereinfacht darzustellen, wird während der Modellierung ein Stereotyp als zusätzliches Element eingeführt. Sie werden benutzt, um Modellelemente zu klassifizieren, z.B. eine KLasse als Schnittstellenklasse zu definieren, oder Attribute und Operationen mit Überbegriffen zu versehen. Dem Aussehen nach unterscheidet man innerhalb von Diagrammen textuelle Stereotypen und visuelle Stereotypen. Textuelle Stereotypen bestehen aus einem Namen, der von spitzen Doppelklammern eingeschlossen ist (<<stereotyp>>). Visuelle Stereotype sind Icons, die anstelle oder mit textuellen Stereotypen verwendet werden.

Stereotyp

1.2.5 Eigenschaften

Eigenschaften sind zusätzliche Merkmale von Elementen, die wie Zusicherungen ebenfalls in geschweiften Klammern angegeben werden. Beispiel für Eigenschaften sind:

2 Klassendiagramme

2.1 Ausprägungen

Klassendiagramme gibt es in drei Ausprägungen:

2.1.1 Klassenstruktur

Ein Strukturdiagramm besteht aus drei Abschnitten und beschreibt damit die wesentlichen Eigenschaften einer Klasse und ihre Member

Klassenname

Im Abschnitt 1 wird der Klassenname zentriert und fett gesetzt.
Weitere Merkmale wie die Eigenschaft {abstract} (unterhalb des Klassennames oder das Stereotyp <<interface>> (oberhalb des Klassennamens können angegeben werden

Attribute

Der 2. Abschnitt enthält eine Liste der Attribute, die in einer Klassen zu definieren sind. Je nach Projektphase kann sich die Beschreibung eines Attributs auf die Nennung seines Namens beschränken oder technische Merkmale wie Zugriffsmodifikatoren, Datentypen oder Eigenschaften enthalten.

Die vollständige Syntax einer Attributbeschreibung:

[sichtbarkeit][/]name[:typ][multiplizität][=initwert][eigenschaften]
Eckige Klammern drücken aus, dass die Angabe optional ist.

Sichtbarkeit

Gibt an ob nur die Klasse, oder alle Klassen desselben Pakets, oder nur die Klasse und deren Kinder, oder alle auf ein Attribut einer Klasse zugreifen kann

Dazu gibt es vier Symbole:

Symbol Bezeichnung Bedeutung
- Private kann nur innerhalb der Klasse "gesehen" werden in dem das Attribut definiert wurde.
~ Package Private Sichtbar in allen Klassen desselben Pakets
# Protected Sichtbar in der Klasse in dem das Attribut definiert ist und zusätzlich in allen Kindklassen
+ Public Überall sichtbar
Abgeleitete Attribute

Abgeleitete Attribute werden mit einem Schrägsstrich "/" gekennzeichnet. Bei abgeleiteten Attributen handelt es sich nicht um eine Variable sonder vielmehr um einen Wert der zur Laufzeit des Programmes von anderen Werten abgeleitet wird. Klassisches Beispiel ist das Alter welches mit dem Geburtsdatum und dem aktuellen Datum errechnet werden kann.

Name

Name eines Attributs. Schon jetzt schadet es nicht den Namen eines Attributs nach der Syntax von Programmiersprachen zu bilden.

Typ

Der Typ eines Attributs kann auf Basis von Datentypen aktueller Programmiersprachen angegeben werden: z.B. int, integer, boolean etc.
Genauso wäre es möglich "Ganzzahl" oder "Gleitpunktzahl" anzugeben.

Multiplizität

hiermit gibt man an wie oft ein Attribut vorkommt. Standard ist 1. Ist ein Attribut optional oder kommt mehrmals vor wird die Anzahl als Zahlenintervall in eckigen Klammern beschrieben.

[0..1] Optionales Attribut
[0..*] Attribut kommt garnicht oder beliebig oft vor
[1..*] Attribut kommt mindestens 1 mal oder beliebig oft vor
[5..8] Attribut kommt mindestens 5 mal aber maximal 8 mal vor
[11] Attribut kommt genau 11 mal vor
Anfangswert

Dient dazu für das Attribut einen Anfangswert anzugeben

Eigenschaften

Gibt besondere Merkmale des Attributs an. Entweder in Form von Randbedingungen oder vordefinierten Schlüsselwörtern. Diese werden dann in geschweifte Klammer gesetzt.

{readonly} Nach der Initialisierung des Attributs, darf kein neuer Wert zugewiesen werden
{ordered} Das Attribut liegt in einer bestimmten Reihenfolge vor. (nur bei Multiplizität > 1)
{unique} Das Attribut darf nur einmal vorkommen (nur bei Multiplizität > 1)
Statische Attribute

Handelt es sich um ein Klassenattribut, muss dieser Eintrag vollständig unterstrichen werden.

Beispiele
nettoPreis Einfachste Ausprägung
~anzahl: int = 1 Attribut ist sichtbar in allen Klassen desselben Package. Ist vom Typ int und wird mit 1 initialisiert.
-themen: string[1..*] {unique} das Attribut ist nur in der Klasse sichtbar in der es definiert wurde. Es ist ein Array oder eine Colllection aus Zeichenketten die Minium ein Element umfasst. Zudem darf ein und dasselbe Element nur einmal vor kommeb

Operationen

der 3. und letzte Abschnitt des Klassendiagrammes beherbergt die Operationen (Methoden).

Die Syntax:

[sichtbarkeit]name([parameterliste])[:typ][eigenschaften]
Sichtbarkeit

Wie bei den Attributen gelten auch bei den Operation die Zugriffsmodifikatoren private, package private, public, protected

Name

Im Grunde gibt es keine Vorgaben für die Namensfindung. Es macht jedoch Sinn die allgemeinen Regeln bei den Programmiersprachen zu nutzen, damit später beim erstellen des Programmcodes Zeit gespart werden kann. Zum Beispiel würde es Sinn machen als Namen Verben (Tätigkeitswörter) zu verwenden.

Parameterliste

Dieser Teil der Operationsbeschreibung erklärt die Parametervariablen als kommagetrennte Liste von Vereinbarungen nach dem Schema:

[richtung]name:typ[multiplizität][=standardwert][eigenschaften]

Das Schlüsselwort richtung steht für die Richtung des Datenflusses:

in hier werden die übergebenen Argumente nur gelesen
out die übergebenen Argumente werden durch die Operation nur beschrieben, jedoch nicht gelesen
inout hier kann beides passieren. lesen und schreiben
return steht für Rückgabeparameter; alternativ dazu kann auch nach dem Operationsnamen ein Ergebnistyp angegeben werden

Name, Datentyp und Multiplizität unterliegen den gleichen Regeln wie bereits früher beschrieben.

[=standardwert] beschreibt den Wert, den der Parameter annehmen soll, wenn ihn der Aufrufer nicht mit einem Wert versorgt

Die [eigenschaften] von Parametervariablen entsprechen denen von Attributen

Typ

Hier gilt das gleiche wie für Typen bei den Attributen

Eigenschaften

Erlaubt sind selbst erdachte Zusicherungen und folgende vordefinierte Eigenschaften:

{query} Die Operation nimmt keine Änderung an den Attributen vor
{ordered} So eine gekennzeichnete Operation liefert eine geordnete Liste
{unique} aus dieser Operation bekommt man eine Liste ohne Duplikate
{redefines} Hier wird eine geerbte Operation überschrieben
{raisedExceptions=...} Nennung der Exceptions die bei der Operation auftreten können
Statische Methoden

Handelt es sich bei der Operation um eine Klassenmethode, muss der Eintrag unterstrichen werden

Abstrakte Methoden

die gesamte Methodenbeschreibung wird kursiv gesetzt. Alternativ hängt man das Schlüsselwort {abstract} an.

Beispiele für Operationsdefinitionen
-istSchaltjahr():boolean

Es handelt sich hier um eine private Operation ohne Parameterliste, und liefert als Ergebnis boolean

#suchen(knr:long):Kunde

Diese Operation wird nur in der Klasse und deren Kindklassen "gesehen". Sie erwartet einen Parameter vom typ long (als reinen Eingabeparamter) und liefert als Ergebnis ein Objekt vom Typ Kunde ab.

2.2 Vererbung

In dieser Ausprägung des Klassendiagramms werden die Generealisierungs- und Spezialisiierungsbeziehung beschrieben:

Das Interface ist in diesem Sinne auch eine Generalisierung, da es Gemeinsamkeiten der implementierenden Klassen zusammenfasst. diese nahe Verwandschaft der Beziehungen wird auch durch die ähnlichen Symbole ausgedrückt:
Die Ableitungsbeziehung verwendet einen durchgezogenen Pfeil mit Dreieckspitze hin zur generalisierten Klasse. Die Implementierungsbeziehung verwendet im Unterschied eine gestrichelte Linie mit Dreiecksspitze, welche zum generalisierenden Interface zeigt

2.2.1 Ableitung

Die Ableitungsbeziehung wird durch einen Pfeil beschrieben, der von der Kindklasse zur Elternklasse geführt wird. Dabei drückt sie aus, dass die Kindklasse alle Merkmale der Elternklasse erbt, daneben aber auch eigene Merkmnale definiert

Ob eine Mehrfachvererbung (Kindklasse hat mehrere Ableitungspfeile) und ob besondere Methoden wir Kondstruktoren und Destruktoren ebenfalls vererbt werden können, ist von der gewählten Programmiersprache abhängig. Somit bietet UML entprechend keine Vorschriften.

ableitung

2.2.2 Implementierung

Die Implementierungsbeziehung wird durch einen Pfeil beschrieben der von der implementierenden Klasse zum Interface führt, oder durch einen Kreis(Ball), der das Interface repräsentiert und der mit der implementierenden Klasse durch eine durchgezogene Linie verbunden ist. Sie drückt aus, dass die implementierende Klasse alle abstrakten Methoden des Interfaces übernimmt; demetnsprechend muss die Klasse alle dieser Methoden konkretisieren (überschreiben) oder als abstrakte Klasse gekennzeichnet werden.

In einer weiteren Darstellungsform kann ausgedrückt werden, dass zwei Klassen „über ein Interface" kommunizieren, d. h. dass eine Serverklasse ein bestimmtes Interface implementiert und eine Clientklasse nur solche Methoden nutzt, die in dem Interface vereinbart sind. Auf diese Art entsteht zwischen den beiden Klassen eine lose Verbindung (Loose Coupling); sie sind damit weitgehend unabhängig voneinan¬der, und es ist eher möglich, eine der beiden Klassen inhaltlich zu ändern ohne die andere anpassen zu müssen. In dieser Darstellungsform wird das Interface wieder als Kreis dargestellt, der mit der (implementierenden) Serverklasse verbunden wird und von der (nutzenden) Clientklasse umfasst wird.

Grafisch sehen diese Formen folgendermaßen aus:

Interface

In dieser Schreibweise wird sehr gut deutlich, welche Methoden im Interface vereinbart sind und welche dieser Methoden in der implementierenden Klasse konkretisiert werden. Andererseits wird ein umfangreiches Klassensystem mit einer Vielzahl von Implementierungsbeziehungen in dieser Darstellungsform schnell unübersichtlich.

Interface

In dieser Schreibweise kann die Implementierungsbeziehung wesentlich kompakter ausgedrückt werden; allerdings ist der „Inhalt" des Interfaces nicht mehr erkennbar; er muss in einem separaten Strukturdiagramm ausgedrückt werden.

Interface

Hier wird wiederum ausgedrückt, dass die Klasse A das Interface I1 implementiert (bereitstellt). Zusätzlich wird dargestellt, dass die Klasse B unter Verwendung der Interfacemethoden auf die Dienstleistungen der Klasse A zugreift; I1 ist aus der Sicht von B ein benötigtes Interface. Unter diesen Umständen kann die Komponente A jederzeit gegen eine beliebige andere Komponente x ausgetauscht werden, solange diese ebenfalls das Interface I1 implementiert.

Fortsetzung folgt...

3 Objektdiagramme

4 Anwendungsfalldiagramme

5 Aktivitätsdiagramme

6 Symbole in PAP's

PAP Symbole

6.1 Beispiel 1

Struktogramm für Beispiel1 PAP Umsetzung

6.2 Schleifen

6.2.1 Kopfgesteuerte

Kopf Struktogramm PAP Kopf

6.2.2 Fußgesteuerte

Fuß Struktogramm PAP Fuß

6.2.3 Abbruch

Abbruch Struktogramm PAP Abbruch