Archiv der Kategorie: omg

MindMaps Teil 2

Wie im vorigen Beitrag angekündigt wird jetzt untersucht, wie ein Metamodell für MindMaps aussehen könnte. Dabei soll es am Ende möglich sein, einfache MindMaps als Instanzen des Metamodells darzustellen.

Als Ausgangspunkt dient das UML-Metamodell. Eine MindMap besteht hauptsächlich aus Topics, die untereinander in einer Beziehung stehen. Im Metamodell gibt es daher die Klasse „Topic“. Ein „Classifier“ ist laut der UML-Spezifikation folgendermaßen definiert: „A classifier is a classification of instances, it describes a set of instances that have features in common“. Im Metamodell ist ein „Classifier“ eine Generalisierung von „Topic“.

Topics

Jedes Topic kann in der Mitte eines weiteren MindMap-Diagramms stehen, deshalb gibt es keine Klasse „RootTopic“ mit „SubTopics“, sondern alle Topics sind Instanzen derselben Metamodellklasse. Nichtsdestotrotz muss die Beziehung „Topic“-„SubTopic“ im Modell dargestellt werden, dafür dient eine Assoziation mit Rollenbezeichnung. An dieser Stelle würde eine Komposition dafür sorgen, dass Topics nicht separat angelegt und nachträglich untereinander verbunden werden können. Das kann an dieser Stelle durchaus Sinn ergeben, ich habe mich aufgrund der größeren Flexibilität aber für eine Assoziation entschieden. Mit der „Topic“-„SubTopic“-Beziehung sieht das Metamodell folgendermaßen aus:

SubTopics

Die Beziehung ist ungerichtet, je nach Anforderung kann die Assoziation auch nur in Richtung des SubTopics navigierbar sein.

Im Moment fehlt zur Darstellung des Beispiels des ersten Teils noch der „Link“ zwischen „Verständnis des Lesers“ und „MindMap to class diagram“. Der Link ist eine gerichtete Beziehung zwischen zwei Topics, er wird mit Hilfe der „DirectedRelationship“ des UML-Metamodells modelliert.

Links

Das Beispiel des ersten Teils kann jetzt als Instanz dieses Metamodells dargestellt werden:
Beispiel

Instanzen

UseCases

UseCases sind ein Teil von UML. Und wahrscheinlich der am häufigsten mißverstandene Teil.
Bei der Betrachtung der Interaktion eines „Actors“ mit einem System kann eine Menge von zusammenhängenden Interaktionen zu einem „Szenario“ zusammengefasst werden. Ein Szenario ist eine Instanz eines UseCase. Ein UseCase ist somit eine Menge von verwandten Erfolgs- und Fehlerszenarios.
UseCases werden vor allem für die Erfassung der funktionalen Anforderungen benutzt, sie können aber genauso gut nicht-funktionale Anforderungen beschreiben. Die Erstellung eines UseCase-Modells ist Teil des Unified Process. Und hier beginnen die Mißverständnisse:
Ein UseCase-Modell in diesem Sinne ist kein UML-Modell, sondern ein Textdokument, welches optional ein UML UseCase-Diagramm zur besseren Übersicht beinhaltet. Viele UML-Tools erlauben es, die textuelle Beschreibung eines UseCases in diesem Tool zu verwalten, und daraus ein Textdokument zu generieren. Dieses Vorgehen ist komfortabel, solange das Werkzeug eine Versionierung des Inhalts anbietet. Ohne Benutzung eines UML-Tools werden manuell Word-/OpenOffice-, HTML- oder LaTex-Dokumente erstellt.
Ein neuer Ansatz ist die Erstellung von User Stories; diese sind weniger formalisiert und interessanter zu lesen. Das fördert die Bereitschaft der am Projekt beteiligten Personen, immer wieder die Anforderungen zu lesen.
Für UseCases in Textform gibt es viele Templates und noch mehr Bücher darüber, deshalb hier nur einige Hinweise zu UseCase-Diagrammen in UML:
Das der UseCase oder mehrere Szenarios in Textform ausführlich beschrieben werden, ist der Name des UseCase kurz und folgt dem Schema [Objekt] [Verrichtung]. Bei Actors können Stereotypen zur Unterscheidung zwischen Personen/Rollen und Systemen unterschieden werden. Und zuletzt muss das UseCase-Diagramm aktuell sein, denn es ist normal, dass UseCases hinzukommen oder wegfallen. Kann das UML-Werkzeug das UseCase-Textdokument automatisiert generieren, so ist die Hürde zur ständigen Aktualisierung sehr niedrig.
Abschließend ein Beispiel für die Form der UseCase-Namen im Schema [Objekt] [Verrichtung].

UseCase

Diese Form der UseCase-Namen verdeutlicht, dass ein UseCase-Diagramm nicht alleine als Anforderungsdokument genügt. Wenn hingegen der UseCase-Name aus mehreren Textabsätzen besteht, und damit das Textdukument eingespart wird, so liegen die Anforderungen in einer unstrukturierten und (meist) nicht durchsuchbaren Form vor.

Transaktionen in Sequenzdiagrammen

Sequenzdiagramme beschreiben Interaktionen zwischen Objekten. Tansaktionen sind kein Teil einer Interaktion (zumindest nicht fachlich gesehen), sondern ein Querschnittsthema. Deshalb müssen sie bei Sequenzdiagrammen nicht modelliert werden.
Will man trotzdem zu Dokumentationszwecken die Transaktionsgrenzen zeigen, so kann man sie entweder explizit oder implizit darstellen. Explizit durch eine Interaktion mit dem TransactionManager (begin()- und commit()-Aufrufe), wie es folgendes Bild zeigt:
explicit transaction management in sequence diagrams

Bei der impliziten Darstellung geht man davon aus, dass ein Sequenzdiagramm eine Transaktion darstellt. Neue Transaktionen werden dann durch eine Referenz auf ein anderes Diagramm modelliert, zum Beispiel in folgenden Diagrammen, in denen der Aufruf eines Clients eine neue Transaktion auf dem Server startet:
transactions: caller with separate Tx
new Transaction (implicit)

UML2: Properties (Teil 6)

Der vorgehende Teil hat noch die Frage offengelassen, wo der Typ der Assoziation (also der AggregationKind) definiert wird. Die zunächst überraschende Antwort auf diese Frage: An der Property. Überraschend deshalb, weil die Vermutung naheliegt, dass der AggregationKind an der Assoziation liegt. An dieser Stelle kann jeder Leser sich überlegen, wie er oder sie die Assoziation modellieren würde. Bei mir sehen die Gedanken folgendermaßen aus:

Eine Assoziation verbindet Classifiers. Für gerichtete Assoziationen, sowie für Aggregationen und Kompositionen sind die Enden der Assoziation nicht gleichberechtigt, daher hätte ich die „memberEnd“-Assoziation zwischen „Association“ und „Property“ (siehe das Bild im vorigen Teil) als zwei separate Assoziationen modelliert (mit den Namen „source“ und „target“). Den Typ der Assoziation, also den AggregationKind, hätte ich dann direkt an die Association gehängt, durch die nicht-gleichberechtigten Enden ist dann eindeutig, welches Ende der „Teil“ und welches das „Ganze“ ist.

Warum ist im UML-Metamodell der AggregationKind für „Property“ definiert? In meinen Gedanken bin ich von der (falschen) Annahme ausgegangen, dass eine Assoziation nur zwei Enden haben kann. UML als Universalsprache erlaubt aber beliebig viele Enden für Assoziationen. Und damit funktioniert mein Ansatz mit verschiedenen Rollen für die Assoziationsenden nicht mehr. Mir stellt sich aber jetzt die Frage, ob sich der ganze Aufwand für die Unterstützung von Assoziationen mit mehr als zwei Enden lohnt. Das Metamodell erlaubt es nämlich, jedes Ende einer Assoziation als „Ganzes“ einer Teil-Ganzes-Beziehung zu modellieren, ein Widerspruch, den man durch Constraints im Metamodell verbieten muss. Da ich persönlich noch nie eine Assoziation mit mehr als zwei Enden modelliert habe, erscheint mir der Nachteil, ein Teil der Struktur der Metamodells in Constraints verlagern zu müssen, größer als der Vorteil, beliebig viele Enden zu unterstützen. Aber wie so oft ist das eine Abwägungssache.

Abschließend das detaillierte Metamodell von „Property“, diesmal mit dem AggregationKind.

Properties

UML2: Kompositionen und Assoziationen (Teil 5, Praxis)

Im UML-Metamodell werden Beziehungen zwischen Klassen als Assoziationen oder als Kompositionen modelliert. Verglichen mit dem Sprachumfang von UML fehlt im Metamodell die Aggregation. Jeder, der schon in einem Team Klassendiagramme diskutiert hat, hat wohl die Erfahrung gemacht, das der Typ einer Beziehung (der AggregationKind) stellenweise schwer festzulegen ist. Es gilt die folgende Semantik für AggregationKind:

  • „none“: Eine Beziehung zwischen „gleichberechtigten“ Partnern
  • „shared“: Eine Teil-Ganzes Beziehung (Aggregation)
  • „composite“: Eine Teil-Ganzes Beziehung, die enthaltende Klasse ist für Existenz und Speicherung der Teile verantwortlich (Komposition)

Naturgemäß ist eine Aggregation schwer von einer Komposition zu unterteilen, eine Komposition ist eine stärkere Bindung (durch die Existenzabhängigkeit). In der Praxis fangen aber genau hier die Diskussionen an. Die Frage, ob ein Teil einer Komposition nur vom Ganzen erzeugt werden darf, oder auch von außen übergeben werden darf, führt oft zu erbitterten Grabenkämpfen. Die ewige Frage „Komposition oder Aggregation“ löst Craig Larman rigoros und pragmatisch: Für ihn ist eine Aggregation ein Placebo ohne festgelegte Semantik, und soll daher nicht benutzt werden. Eine Lösung, die auch für das UML-Metamodell verwendet wurde (denn das UML-Metamodell besteht ausschließlich aus Assoziationen und Kompositionen). In der UML-Superstructure Specification wird das sehr gut durch folgendes Zitat ausgedrückt:
Precise semantics of shared aggregation varies by application area and modeler.

In UML bestehen Relationships nicht nur aus einer Instanz von „Association“, sondern es existieren Enden, die vom Typ „Property“ sind (siehe das Diagramm unten). Diese Enden können entweder einem Classifier gehören, oder sie gehören als „ownedEnd“ der Association. Das Metamodell erlaubt Beziehungen mit beliebig vielen Enden (genauer: mit 2..* Enden), in der Praxis haben die meisten Beziehungen zwei Enden. Eine Property kann eine „opposite“-Property referenzieren, dies ist über die derived-Beziehung „/opposite“ realisiert.

Im UML-Metamodell gibt es noch eine Spezialisierung von „Relationship“, die „DirectedRelationship“. Diese dient als Basisklasse für gerichtete Beziehungen, z.B. einem PackageImport.

Relationships in the Metamodel

UML2: Generalisierungen (Teil 4)

Nach dem vorangegangenen Artikel über die Struktur des Metamodells geht es in diesem Text um konkreten Inhalt, nämlich die Generalisierung. Zunächst ein Zitat aus der UML Superstructure Specification:
„A generalization is a taxonomic relationship between a more general classifier and a more specific classifier. Each instance of the specific classifier is also an indirect instance of the general classifier. Thus, the specific classifier inherits the features of the more general classifier.“
Das obige Zitat beinhaltet eine Referenz auf „features“, damit sind „StructuralFeatures“ und „BehavioralFeatures“ gemeint, also (vereinfacht ausgedrückt) Properties und Operationen.

Wie wird die Generalisierung im Metamodell modelliert? Das obige Zitat drückt bereits aus, dass die Generalisierung eine Beziehung zwischen „Classifiers“ ist. Daher liegt die Vermutung nahe, dass die Generalisierung wie in folgendem Diagramm modelliert ist:
too simple generalization
Während die Beziehung im obigen Diagramm ausreicht, um die Generalisierung zu realisieren, ist das Metamodell von UML doch etwas komplexer. Das hat den Hintergrund, dass im Metamodell schon abstrakte Klassen für Beziehungen aller Art beinhaltet (und die Generalisierung ist eine Beziehung zwischen Classifiers), und das Konzept von Beziehungen auch für die Generalization benutzt wird. Trotzdem ist das obige Diagramm korrekt, denn die Informationen über die „Parents“, also die generellen Classifiers, werden über eine „derived“-Beziehung (erkennbar an dem Slash „/“ für abgeleitete Properties) so abgebildet. Das bedeutet, dass die Generalisierung über die Klasse „Generalization“ modelliert wird, aber die Informationen gleichzeitig über die „general“-Property verfügbar sind.
Im folgenden Bild ist der Ausschnitt aus dem UML Metamodell, der Generalisierungen definiert, abgebildet:
Generalization for Classifiers

An dieser Stelle noch ein Verweis auf den Teil 1 des Metamodells, wo schon die Modellierung der Superklassen angedeutet wurde. Dort hat eine Klasse die Property „superClass“, die von der Generalisierung abgeleitet ist.

UML2: Struktur des Metamodells (Teil 3)

Im vorigen Artikel (UML2 Teil 2) wird ein Teil des UML-Metamodells, ausgehend von „Class“, beschrieben. Diese Vererbungshierarchie ist eigentlich recht intuitiv, wenn die verschiedenen abstrakten Klassen des Metamodells bekannt sind. Hier eine unvollständige Übersicht über verschiedene Klassen:
– Element
– NamedElement
– Namespace
– PackageableElement
– Package
– TypedElement
– Type
– RedefinableElement
– Classifier
– Class
– DataType
– PrimitiveType
– Enumeration
Das intuitive Herangehen an die Struktur des Metamodells besteht nun darin, eine Klasse herauszunehmen und mit den übrigen Klassen folgende Frage zu beantworten: „Ist die [herausgenommene Klasse] eine [übrige Klasse]“?
So zum Beispiel für den „PrimitiveType“ (in UML gibt es die primitiven Typen „Boolean“, „Integer“, „UnlimitedNatural“ und „String“): Ein „PrimitiveType“ ist allein dem Namen nach ein „Type“. Ob er jetzt direkt mit Type verbunden ist, oder indirekt, kann man jetzt noch nicht beantworten. Ein „PrimitiveType“ ist auch ein „DataType“ (da z.B. „Integer“ ein „DataType“ ist). Exkurs über „DataType“: Ein „DataType“ ähnelt einer „Class“, besitzt aber keine inherente Identität (alle Instanzen mit demselben Wert sind gleich).
Ist ein „PrimitiveType“ ein „Classifier“? Ein Classifier beschreibt eine Menge von Objekten, ein PrimitiveType repräsentiert ebenfalls eine Menge von Objekten, also ist ein PrimitiveType auch ein Classifier. Ist Classifier eine direkte Generalisierung von PrimitiveType? Das kann durch Untersuchung der bisher identifizierten SuperKlassen von PrimitiveType herausgefunden werden, also durch Beanwortung der Frage „Repräsentiert DataType eine Menge von Objekten“? Ja, ein DataType ist ebenfalls ein Classifier, also ist ein Classifier keine direkte Generalisierung von PrimitiveType, sondern von DataType.
Eine „Class“ beschreibt ebenfalls eine Menge von Objekten, also ist auch sie ein „Classifier“. Welche Generalisierungen von „Classifier“ gibt es? Ein „Classifier“ kann als „Type“ von Operationen oder Properties benutzt werden, daher ist ein „Type“ eine Generalisierung von „Classifier“. Ein „Namespace“ beinhaltet „NamedElements“, ein „Classifier“ kann „Properties“ beinhalten, also ist „Namespace“ eine Generalisierung von „Classifier“.
Ein „Classifier“ kann in einem Package liegen, also muss „Classifier“ ein „PackageableElement“ sein. Da ein „Type“ ebenfalls in einem Package liegen kann, und genereller als ein „Classifier“ ist, ist „PackageableElement“ eine direkte Generalisierung von „Type“.
Die positive Beantworung der Frage „Ist ein ‚Classifier‘ ein ‚PackageableElement‘?“ liefert einen Kandidaten für eine Generalisierung, durch Überprüfung der bereits identifizierten weiteren Kandidaten werden alle Metaklassen in eine relative Beziehung zueinander gesetzt. Den bildlichen „Nagel in der Wand“, an dem das Konstrukt aufgehängt wird, liefert dann das BasisElement von UML, die Metaklasse „Element“.
Abschließend eine Übersicht über die Generalisierungsbeziehungen im UML-Metamodell:

Struktur des UML Metamodells

UML2: Das Metamodell (Teil 2)

Als Fortsetzung der begonnenen Erklärung des Metamodells von UML, setzt dieser Text an der wohlbekannten Stelle der „Klasse“ die Serie fort.
Welche Merkmale besitzt eine Klasse? Sie hat einen Namen und liegt in einem Package. Zunächst der Name, ohne Kenntnisse des Metamodells liegt der Gedanke nahe, dass eine Klasse ein String-Attribut namens „name“ besitzt (wie im folgenden Bild dargestellt).

class with a name-property
Im UML-Metamodell besitzt die Klasse aber kein Attribut „name“, sondern erbt dieses von „NamedElement“.

inheritance of the name-property

Dieses Diagramm zeigt verschiedene Dinge: Erstens wird deutlich, dass das UML-Metamodell mit Mehrfachvererbung arbeitet (selbst das Meta-Metamodell benutzt Mehrfachvererbung). Zweitens ist eine Klasse gleichzeitig ein „Type“, Properties und andere TypedElements können also als Typ eine Klasse (genauer: die Instanz von „Class“ des Metamodells) haben. Drittens ist eine Klasse auch ein Namespace, sie kann also andere Elemente (zum Beispiel PackageableElements oder NamedElements) enthalten. Damit kann man innere Klassen, Properties, Operationen und vieles mehr in eine Klasse legen.

UML2: Das Metamodell (Teil 1)

UML besitzt, wie bereits in „Metamodelle anschaulich“ Teil 1 und Teil 2 beschrieben, ein Metamodell. Dieses Metamodell ist auf den Webseiten von OMG frei verfügbar. Wen interessiert das UML-Metamodell? Der Anwender von UML-Werkzeugen kommt nicht mit dem Metamodell in Kontakt, denn das Tool mit seinem eingebauten Metamodell gibt dem Benutzer gar keine andere Möglichkeit, als ein korrektes UML-Modell zu erstellen. Trotzdem ist meiner Meinung nach eine Kenntnis des UML-Metamodells für jeden Anwender von Vorteil, da die UML-Tools zum einen teilweise ein reduziertes UML-Modell verwenden, zum anderen aber auch bei einem guten UML-Werkzeug Kenntnisse der Semantik nötig sind. Zum Beispiel bei der Frage, welche Bedeutung die Beziehungsenden einer Assoziation besitzen, und wem sie „gehören“.

Es gibt noch weitere Gründe, das Metamodell anzuschauen. Bei Zeichnungen am Whiteboard liegt es nämlich beim Zeichner, ein valides UML-Modell zu erstellen. Während Klassendiagramme noch von den meisten Entwicklern beherrscht werden (abgesehen von Constraints und tenären Beziehungen), ist es relativ selten, ein korrektes dynamisches Diagramm an einer Wand zu erblicken. Die Ausrede, dass ein korrektes UML-Diagramm am Whiteboard gar nicht vonnöten ist, zählt auch nicht wirklich. Denn nur, wer die unterschiedlichen Möglichkeiten in den Interaktionen von Objekten kennt, kann auch ein sinnvolles Diagramm zeichnen. Und selbst, wenn man diese Möglichkeiten auch ohne UML-Erfahrung kennen kann, so ist die Benutzung von UML doch besser als die Erfindung einer eigenen, gleichwertigen Sprache.

Und schließlich gibt es noch UML-Zertifizierungen von OMG. Meiner Meinung nach sollte bei dieser Zertifizierung besser ein Beispielprojekt in UML modelliert werden. Da aber wahrscheinlich die Korrektur eines frei erstellen Modells zu aufwändig ist, besteht diese Zertifizierung aus Fragen zum Metamodell (eine Zertifizierung, wo ein Modell für ein Beispielprojekt erstellt werden muß, ist der „Sun certified Enterprise Architect“). Für die Prüfung sind tiefe Kenntnisse eines Teils des Metamodells erforderlich, und dafür muss die UML-Spezifikation durchgearbeitet werden.

Die UML-Infrastructure beginnt mit der Definition eines „Elements“. Das „Element“ ist der Baustein, auf dem alle anderen Klassen des Metamodells aufbauen. Leider ist es aber auch ein sehr unintuitiver Beginn einer Definition. Eine „Klasse“ ist den meisten Leuten viel geläufiger als ein abstraktes „Element“. Warum also nicht das Metamodell mit einer Klasse beginnen?

Eine Klasse ist ein „Classifier“. (Andere Classifier sind z.B. „DataType“, „PrimitiveType“ und „Enumeration“).

Metamodel of a class and classifier

Eine Klasse kann mehrere Superklassen haben. (Die „Generalization“-Beziehung wird später definiert).

a class has a superClass

Der Slash „/“ an dem Assoziationsende bedeutet „derived definition“. Die Information über die SuperKlassen kann also aus anderen Modellelementen (hier kommt wieder die Generalisierung ins Spiel) abgeleitet werden.

Damit endet der erste Teil, die Einführung wurde etwas ausschweifender als gedacht, in den nächsten Teilen kommt deutlich mehr vom UML-Metamodell.