Softwaretechnik, 04. UML Klassendiagramme in der Systemanalyse
Material für die Softwaretechnik Vorlesung, Bernhard Rumpe
UML Klassendiagramme in der Systemanalyse und zur Generierung
Diese Erklärung ist gedacht für Studierende als Einführung in die Vorlesung Softwaretechnik, die
- verstehen wollen welche Grundkonzepte die UML Klassendiagramme zur Verfügung stellen, und
- wie Klassendiagramme intellektueller Notation dargestellt werden
können, um dann als Eingabe für das
MontiGem
Tooling genutzt zu werden, das daraus einen ersten Prototypen für ein Business Informationssystem erstellt.
Diese Erklärung beinhaltet einige aber nicht alle Abschnitte des Kapitel 4 der Softwaretechnik Vorlesung. Eine vertiefende und vollständigere Einführung zu UML Klassendiagrammen findet sich in den UML-Büchern, speziell Buch 1, Kapitel 2.
- … und viele weitere Anwendungsmöglichkeiten, zum Beispiel als Referenzmodelle, als Architekturbeschreibungen, als Datenmodelle oder als Konzeptmodelle zur Beschreibung der relevanten Konzepte eines zu implementierenden Systems.
- Die wesentlichen Merkmale der Objektorientierung: Klassen, Objekte als deren Instanzen, Vererbung, Polymorphie.
-
Ein Klassendiagramm visualisiert eine Sammlung von Klassen, sowie einige später gezeigte Konzepte, wie die Vererbung und Assoziationen zwischen den Klassen.
-
Ein Klassendiagramm zeigt damit sowohl die Beziehungen zwischen Klassen, als auch wie hier zu sehen die Interna einzelner Klassen, hier eine Klasse mit vier Attributen und fünf Methoden, deren Typisierung und Sichtbarkeit.
- Abstrakte Klassen, Interfaces und instantiierbare (normale) Klassen sowie hier nicht gezeigte Enum-Klassen gibt es ganz analog zu Java.
-
Anders als in Java ist Mehrfachvererbung (siehe
HiWi
) möglich. Sollte diese zum Einsatz kommen, so ist in einer späteren Phase zu überlegen, wie diese in einer Programmiersprache ohne Mehrfachvererbung zu realisieren ist. Sollten Sie eine HiWi-Stelle suchen: Melden Sie sich bei uns: Website of the SE -
Bemerkung: Dafür gibt es Standardstrategien, denn es gibt
immer Strategien ein in der Modellierung verwendetes aber in einer Implementierung fehlendes Konstrukt adäquat zu repräsentieren. Die einzige Implementierungsbarriere ist fehlende Ausführbarkeit.
-
Assoziationen lassen sich in einem Klassendiagramm sehr gut verwenden, um die Beziehungen zwischen den Objekten einer Klasse einzusetzen.
-
In objektorientierter Programmierung ist das Konzept “Assoziation” ebenfalls nicht direkt vorhanden und deshalb müssen Assoziationen durch (später diskutierte) ggf. komplexere Konstrukte ersetzt werden.
-
Es gibt normale Assoziationen und Komposition sowie qualifizierte Assoziationen (siehe unten).
-
Assoziationen können unter anderem Assoziationsnamen sowie auf beiden Seiten Rollennamen, Kardinalitäten und einen Pfeil tragen.
-
Der Pfeil klärt, ob in diese Richtung navigiert werden kann (zum Beispiel kennt die Person ihre Messages).
-
Eine Assoziation beschreibt grundsätzlich und immer die Beziehung zwischen Objekten der Klassen auf beiden Seiten. Die Objekte sind dann durch entsprechende Links miteinander verbunden, die durch die Kardinalität begrenzt werden.
-
Assoziationen und Vererbung haben eine grundlegend unterschiedliche Aufgabe: Vererbung verbindet Klassen, Assoziationen verbinden ihre Objekte durch Links. Eine Subklasse wird deshalb einzeln instantiiert (ein Objekt), eine Assoziation bzw. ihr Link verbindet zwei Objekte.
-
Eine Assoziation kann zweimal dieselbe Klasse verbinden, was eine rekursive Datenstruktur erlaubt, und zum Beispiel Listen, Bäume, oder allgemeine Graphen darzustellen erlaubt. Siehe auch Entwurfsmuster Composite.
-
Komplexere Formen von Assoziationen, die zum Beispiel drei verschiedene Klassen beinhalten sind in der UML möglich, aber wegen der hohen Komplexität eher zu vermeiden und hier auch nicht weiter diskutiert.
- Wir empfehlen die Aggregation nicht zu nutzen, weil die Semantik nicht einheitlich geregelt bzw. im Detail dann unklar ist.
- Komposition tätigt eine scharfe und deshalb auch meist hilfreiche
aber nicht überall einsetzbare Aussage über den kombinierten
Lebenszyklus der komponierten Objekte. Wenn
Reifen
amAuto
ausgetauscht werden können, dann ist es keine dauerhafte Komposition.
-
Für eine effiziente Navigation, gerade bei unbegrenzter Kardinalität (
*
) und gegebenenfalls großen Mengen an Objekten auf der anderen Seite ist ein Qualifikator sehr hilfreich. -
Ein Qualifikator wird auf einer Seite eine Assoziation angegeben und kann dann genutzt werden um direkt das richtige Objekt zu identifizieren.
-
Wird ein Datentyp, etwa
String
oderint
eingesetzt, oder ein Attributname der gegenüberliegenden Klasse (auctionIdent
), so werden Werte dieses Typs als Identifikatoren verwendet. Wer hier an eine Realisierung mit einer HashMap denkt liegt meist richtig. -
Ist
{ordered}
angegeben, so kann eine Implementierung als Liste ziemlich sicher angenommen werden. In diesem Fall ist das ganze Interval von1
bis zur Länge der Liste als Index verwendbar.
- Ist der Qualifikator ein Attribut der gegenüberliegenden Klasse, so
ist eine Besonderheit zu beachten: da das identifizierte Objekt seinen
Identifikator (also seinen eigenen Attributwert) kennt, ist bei allen
Links der Qualifikator-Wert identisch. Beispiel: Alle öffentliche
Telefonbücher haben
"Gerd Müller"
mit derselben Nummer.
- Demgegenüber ist in einem privaten Telefonbuch
"Gerd Müller"
durchaus unter verschiedenen Namen eintragbar - und kennt die dort eingetragenen Namen nicht.
- Was machen wir nun mit Klassendiagrammen, wenn wir sie in der Analyse entwickelt, im Systementwurf präzisiert und für Software zugeschnitten haben? Entweder händisch oder durch Werkzeuge unterstützt Code daraus ableiten. Am aller sinnvollsten ist die vollautomatische Codegenerierung, die in diesen Abschnitt adressiert wird.
- Dieses Bild zeigt die klassische Übersetzung einer Klasse aus dem
Klassendiagramm in
Java
-Code sowie auch inC++
-Code. Wenn man beides benötigt hat man schon einen gewissen Vorteil, weil dadurch nur noch eine redundanzfreie Informationsquelle für die KlasseAuction
existiert. Und wir wissen ja: Redundanz ist immer schwierig, wenn man revolutionäre Software anpasst, weil es zu Inkonsistenz führt und dadurch viel unangenehme Prüfungsaufgaben mit sich bringt.
-
Richtig hilfreich ist ein Generator, wenn man weitere Generierungen damit vornimmt. Und dafür gibt es sehr viele Optionen:
-
Zum Beispiel Serialisierungsfunktionalität: der Transport eines Objekts von einem zum nächsten Prozess, zwischen Server und Client ist oft mit sehr viel Code verbunden.
-
Zum Beispiel die Persistierung in einer Datenbank, das Wiederfinden, etc. lässt sich generieren.
- Ein noch überschaubares Beispiel verbesserter Codegenerierung. Das sind aber dennoch bereits Einsparungen.
-
Spannend wird es auch bei Assoziationen, die im Klassendiagramm, aber nicht in
Java
oderC++
zur Verfügung stehen. Im Beispiel wird eine qualifizierte Assoziation durch eineMap
realisiert und gleichzeitig eine größere Anzahl an darauf operierenden Funktionen zur Verfügung gestellt. -
Dieses Verfahren ist übrigens besonders hilfreich, wenn eine Assoziation in beide Richtungen navigiertwerden kann und aus Effizienzgründen eine redundante Realisierung auf beiden Seiten der Objekte gewünscht ist. Da kann die Konsistenzsicherung gleich mit rein generiert werden, indem man wie hier das benutzte Attribut
privat
macht und die generierten Funktionen entsprechende Konsistenzsicherung vornehmen. Unser unten besprochener GeneratorMontiGem
macht dies.
- Vermeidung lästiger Programmieraufgaben ist einer der wesentlichen Gründe einen Codegenerator einzusetzen: er hilft uns schneller, effizienter und qualitativ besser zu sein, aber insbesondere langweilige Tätigkeiten beim Programmieren zu vermeiden.
-
Natürlich kann mit einer Strukturdefinition, wie sie ein Klassendiagramm bietet kein komplettes System generiert werden, aber ein lauffähiges System mit Grundfunktionalität schon. Und wenn die Generierung so geschickt gemacht ist, wie die des
MontiGem
Generators, dann lässt sich der generierte Code auf vielfältige Weise durch handgeschriebene Teile oder wie später diskutiert auch durch Anpassung des Generators selbst systematisch ergänzen. -
Wir diskutieren die Grundprinzipien der Generierung in Kapitel 9, stellen aber für die Übungen schon mal den
MontiGem
Generator zur Verfügung.
-
Der Generator bringt uns in drei Schritten vom Klassendiagramm zum laufenden System. Und wir ignorieren in dieser Vorlesung, dass auch handgeschriebener Code, GUI Modelle, Verhaltensbeschreibungen und ähnliches mehr noch möglich sind.
-
Mehr Details über die konkrete Nutzung im Übungsbetrieb.
- Wollen Sie ihr eigenes Facebook aufbauen? Anbei ein Referenzmodell
dazu. Mit dem
MontiGem
Generator ist Facebook light schon fast fertig.
And now let us switch to English for a while.
-
The textual CD4A language is designed in the spirit of Java, using similar keywords, types, delimiters for statements “;” and blocks “{“, “}”.
-
The body of a class diagram consists of a list of classes, interfaces, enumerations, associations, and compositions. The order is irrelevant; it is especially allowed to reference later classes early on. We suggest to either put all classes at the top and the associations later or to group a class and related associations into topical sections.
-
Please note that CD4A starts with the keyword
classdiagram
, while some tools also accept keywordumlp
as the starting point. -
The SocNet.cd example used here can also be directly examined.
-
More examples can be found in the CD4Analysis project.
-
To repeat, the bodies of classes are very similar to the classes in the Java language, because the syntax is inspired by Java. The lines 5–8 could directly come from a Java class, also no method or constructor is defined.
-
Neither classes nor interfaces require bodies, e.g., when you don’t know anything about them yet. An empty body can be denoted using a
;
.
-
Associations are not present in Java, yet exhibit a complex set of information.
-
The text form reads from left to right almost identical to the graphical depiction above: Only the name of the association was moved to the left, and the middle contains the iconic forms of the arrow
<->
,->
, etc. -
Note that we use underspecification as a significant construct within modeling languages, meaning that if certain information is not given, nothing is said. I.e. many pieces of information can be refined, for example
--
just tells us that we don’t know in which directions navigation might be available.
-
Role names like
(organizer)
can also be attached on both sides. -
Qualifiers like
[[profileName]]
resemble the box that they are embedded in. CD4A allows two kinds of qualifiers, either the name of an attribute of the other side (in this case classPerson
) or a data type resembling the key values of the qualified association. Semantics is defined in UML/P books by Bernhard Rumpe.
- Compositions follow the same syntax as associations, just with
the keyword
composition
to indicate their compositional semantics.
-
Enumerations are defined with a set of constants as their body.
-
Enumeration constants are visible inside the enumeration and can be used outside only through qualified names (like
RelationType.FRIEND
) or an explicit import statement.
An import
statement similar to Java’s import is available. It allows
to import foreign types, e.g. defined as Java classes, like Date
or
Account
, but also allows to refer to other kinds of models that
define datatypes, such as other class diagrams.
-
This is a core feature of allowing to compose class diagrams that build on each other but are independently developed by different teams of a project or taken from a library.
-
Please note this restriction: when generating from a bidirectional association, the class on the opposite side must be generatable or similarly genrated too. (I.e.
association Person <-> Date
will not work, because of the external classDate
.) -
The mechanism to make other models and libraries known to the compiler is described in the tool calling (see e.g.
--path
).
CD4A generally follows the requirements engineering guideline, which
states that during the requirements elicitation process generic classes
are not really needed and not also not introduced. However, it is
sometimes convenient to rely on the most relevant basic generics
directly, which are the four Optional< . >
, Set< . >
, List< . >
,
and Map< . , . >
. But please note that these four directly correspond
to associations that can describe the very same properties, but
the CD4A generator for
associations also produce lots of access and manipulation methods
with integrated data consistency checking and
can be used bidirectionally.
-
CD4A allows derived attributes (and associations), marked by
/
. It is notable that this indicates a dependency of this attribute from other attributes, which, however, there is not made explicit in the model itself. -
The package name first of all describes in which directory the model of the class diagram can be found, but by default also carries over to the packages where the modeled (and finally generated) classes reside. Please note: an explicit statement, which is not shown here, can attach individual packages to each class.
-
Like in Java, the
import
statement is required when external datatypes, classes, etc. are used. Such animport
may refer to another model or in this case to an already existing Java class. A context condition checks whether the used classes actually exist in the local model or in the imports.
-
It is a convention to name enums in UPPERCASE, in CamelCase for classes, interfaces, and enumeration types, and to use uncapped names for attributes.
-
In fact, CD4A applies the same restrictions and capabilities for names as does Java, which means that numbers and the dollar sign
$
are allowed within a name and underscore_
in any position. -
More (sometimes subtle) context conditions apply to give a well-formed model. However, the resulting error message should be detailed enough to explain the problem.
-
As a general guideline, CD4A uses similar naming and visibility conventions as Java does, i.e., enum constants and attributes are visible locally and can be used from outside using their qualification – as described above.
- Note that this description does not infer how the CD4A model is
actually used. During a requirement elicitation activity, such a model
is basically used as a communication vehicle to understand the
underlying data structure. However, appropriate tools (including the
CD4A
andMontiGem
generators) are able to produce a lot of infrastructure for such a class diagram. This can be used both for prototyping and actual use later on. As indicated, this may include data structures, access functions, transport, communication and storage, and potentially also web representation.
MontiGem
MontiGem ist ein Generator für Informationssysteme, welches auf der UML/P basiert, einer Teilmenge der Modellierungssprache UML mit dem Fokus auf die Programmieranwendung. MontiGem wird eingesetzt, um datenzentrierte Anwendungen bzw. deren wesentliche Kernkomponenten und Infrastruktur auf der Basis von Klassendiagrammen (sowie weiteren Modellierungstechniken) zu erzeugen. Ein Beispiel-Modell sieht z.B. so aus:
umlp Verwaltung {
class Person {
int age;
}
class Paper {
List<String> lines;
}
association [1] Person -> (owns) Paper [*];
}
MontiGem nutzt eine textuelle Variante der UML/P Klassendiagramme
und erlaubt im Vergleich zur oben beschriebenen Form als initiales
Keyword umlp
(wie im Beispiel gezeigt) synonym zu classdiagram
.
Analog dazu haben Modellartefakte die Endung .umlp
.
Weiterhin erlauben import
-Statements spezielle Datentypen/
Klassen in das aktuelle Diagramm einzubinden und dort nutzbar zu
machen.
Wir werden MontiGem für die Übungsaufgaben benutzen, um damit direktes Feedback für die qualitativ hochwertige Modellierung von Strukturen zu gewinnen. Das Tool kann aus UML/P Klassendiagrammen lauffähige Applikationen generieren, die Sie dann auf Nützlichkeit ihrer Modelle überprüfen können. Konkret haben wir das Tool in Kombination mit dem Gruppen-orientierten Abgabemechanismus über gitlab so eingerichtet, dass eine interaktive Website generiert wird. Wir stellen diese Website für Sie unter passender URL und Zugangsdaten bereit. Bitte bedenken Sie, dass die Website u.A. durch Gitlab CI/CD Pipelines und unsere Server bereitgestellt werden muss. Es kann deswegen zu leichten Verzögerungen bis zum Sichtbarwerden geben.
Die oben genannte Web-Applikation wurde aus der Datei Verwaltung.umlp
generiert. Um Änderungen am generierten System vorzunehmen, pushen Sie
Änderungen des Modells auf den Default-Branch Ihres Git-Repositories.
Die letzte erfolgreiche Pipeline veröffentlicht Ihr generiertes System
automatisch.
Wir hoffen hier einen guten Zugang zu den wichtigsten Konzepten der Klassendiagramme als Teil der UML Modellierungssprache gegeben zu haben. Wir haben gezeigt, wie eine textuelle Fassung der Klassendiagramme definiert werden kann, die dann von unserem Werkzeug MontiGem in einen Prototypen eines laufenden Softwarsystems übersetzt wird.
Eine solche Übersetzung liefert eine gute Grundstruktur auf der sich dann ein komplettes System aufbauen lässt. Allerdings ist hier natürlich noch viel zu tun, denn es ist weder das Rechte/Rollen-Konzept festgelegt, noch Algorithmen zur Verarbeitung und Visualisierung der Daten, sowie meist gewünschte spezielle Anzeigeformen definiert. Es gibt allerdings einen Datenbank-basierten Speichermechanismus, grundlegende Anzeige- und Editier-Webseiten, einen kollaborativen Kommunikationsmechanismus und insbesondere für Entwickler interessant: die Möglichkeiten den generierten Code wie ein Framework zu behandeln und applikationsspezifisch anzupassen.
Join our mailing list for updates regarding courses and theses: