Archiv der Kategorie: uml

Überprüfen des Modells mit Objektdiagrammen

Über objektorientierte Analyse / objektorientiertes Design gibt es zahlreiche Bücher. Ziel ist es, ein für Software nutzbares Modell einer Domäne zu erstellen. Deshalb ist das Klassendiagramm das meistgewählte Werkzeug dafür.

Der Unterschied zwischen einer Klasse und einem Objekt besteht in ihren unterschiedlichen Metaebenen: Das Objekt ist Instanz einer Klasse, liegt also eine Metaebene tiefer. In einer Domäne oder auch im Alltag kommen aber nur Objekte vor (es wird immer mit Instanzen gearbeitet). Die Objekte werden bei der Analyse durch Abstraktion auf Klassen zurückgeführt.

Ein Beispiel: Der interessierte Naturfreund stellt sich beim Beobachten eines Fischs die Frage, zu welcher Art, zu welcher Klasse dieses Objekt gehört. In einem guten Bestimmungsbuch sind deshalb die Pflanzen- und Tierarten gezeichnet statt fotographiert, um individuelle Merkmale auszublenden und nur die charakteristischen Merkmale der Klasse darzustellen.

(aus: Dr. E. Bade: Handbuch für Naturaliensammler. Das Bild zeigt einen Dorsch oder dorschartigen Fisch und keinen Lachs)
(aus: Dr. E. Bade: Handbuch für Naturaliensammler. Das Bild zeigt einen Dorsch oder dorschartigen Fisch und keinen Lachs)

(aus: Dr. E. Bade: Die mitteleuropäischen Süßwasserfische. Weniger detailliert als die vorige Zeichnung, aber ein echter Lachs)
(aus: Dr. E. Bade: Die mitteleuropäischen Süßwasserfische. Weniger detailliert als die vorige Zeichnung, aber ein echter Lachs)

Auch in der Objektorientierung sind zunächst die Objekte bekannt. Es wäre naheliegend, damit ein Modell der Instanzen, der Objekte zu erstellen. Der heute übliche Weg ist aber, direkt ein Klassendiagramm zu erstellen. Trotzdem ist meiner Meinung nach ein Modell der Objekte genauso wichtig; wenn schon nicht zum Erfassen der Domäne, dann wenigstens zum Überprüfen, ob die Klassen ein korrektes Abbild der Instanzen der Domäne erlauben, denn nur dann erfüllt das Klassenmodell die Anforderungen.

Als Beispiel das Modell eines Lachs:

Modell eines Lachs

Für die Instanzen der Domäne hier ein Zitat aus „Die mitteleuropäischen Süßwasserfische“ von Dr. E. Bade:
„Die Färbung des Rückens ist in der Regel blaugrau, Bauch und Seiten silbern (…). Die Rückenflosse ist grau und trägt oft eine Reihe schwarzer kleiner Flecken an der Basis, die übrigen Flossen sind an ihrer Einlenkung gelblich oder rötlich, an ihrem freien Rande schwärzlich. Besonders lebhaft werden die Farben zur Laichzeit (…). Zur Laichzeit ist bei den Männchen der Bauch nicht selten purpurrot und auch die Flossen besitzen einen rötlichen Anflug.“

Mit Hilfe dieser Information kann das Klassenmodell überprüft werden, indem ein Objektdiagramm erstellt wird:

Objektdiagramm einer Lachsinstanz

Hinweis: In vielen UML-Tools gibt es keinen separaten Diagrammtyp für Objektdiagramme, die Instanzen können dann in einem Klassendiagramm modelliert werden.
Das Objektdiagramm zeigt einige Schwächen des Modells:
– Das Gewicht ist ohne Einheit angegeben, offensichtlich ist der Wert das Gewicht in Gramm
– Die Fischinstanz kann beliebig viele Flossen besitzen, allerdings sind die Flosseninstanzen im Diagramm nur durch den Objektnamen in ihrer Position bestimmt. Der Objektname ist nur im UML-Diagramm vorhanden, in Java sind alle Objekte anonym.
– Die Unterscheidung zwischen paarigen Flossen (Brustflosse, Bauchflosse) und unpaarigen Flossen fehlt.

Fazit: Das Objektdiagramm ist das Mittel zum Testen, wie sich die Domäne mit den Klassenmodell abbilden läßt.

Vortrag über „Technische Konzepte“

Auf Bitte eines Unternehmens habe ich einen Vortrag über „Technische Konzepte“ erstellt. Die Zielgruppe sind fachfremde, die beruflich mit IT-Projekten und Entwicklern in Berührung kommen. Als Einleitung geht der Vortrag auf den Entwickler ein und motiviert, warum Dokumentation in Form von Technischen Konzepten so entscheident ist.

Die Datei des Vortrags beinhaltet neben den Folien auch Notizen mit Punkten, die während des Vortrags mündlich vorgetragen wurden. Diese sind zum Verstehen notwendig, und immer nach der Folie, auf die sie sich beziehen, plaziert.

Download: Folien und Notizen

UML und Kommunikation wird fortgesetzt

Da die Kommunikation für mich einer der Hauptgründe ist, UML einzusetzen, arbeite ich gerade an einem Vortrag über das Thema. Die Präsentationsfolien werden dann hier veröffentlicht. Der Vortrag geht auf UML und technische Konzepte nach dem 4+1-Modell ein, und richtet sich auch an fachfremde. Eine Betonung liegt auf der Übertragung der Frage „Wenn ich mit einem amerikanischen Unternehmen einen Vertrag abschließe, soll mein Verhandlungsführer dann vor allem Englisch sprechen, oder sich im Vertragsrecht auskennen?“ auf die Softwareentwicklung.

Der Zeitplan sieht vor, dass der Vortrag Mitte Oktober fertig wird.

UML und Kommunikation

Es gibt viele Gelegenheiten, UML einzusetzen. Bei all diesen Möglichkeiten spielt Kommunikation eine wichtige Rolle. Dabei kann es sich um Kommunikation von Architekten mit Entwicklern, vom Product Owner zum Team, oder von einem Programmierer zu sich selbst handeln. UML bietet ein ausreichend abstraktes, aber doch genügend ausdrucksstarkes Kommunikationsmedium.

Bei all den begeisternden Möglichkeiten, die UML bietet, darf ein wichtiger Punkt nicht außer acht gelassen werden: Ziel ist, das die übermittelte Botschaft verständlich ist. Das kann bei einer Zielgruppe, die UML nicht kennt, soweit gehen, dass statt UML besser Pseudocode zur Kommunikation benutzt wird. Oder ein Chef, der seinem Team morgens mit den Worten „und das macht ihr mir noch bis heute Abend fertig, ja?“ einen Zettel mit drei Kringeln, die UML UseCases darstellen, hinlegt: Solange nicht die gewünschte Wirkung eintritt, solange die Botschaft von der Zielgruppe nicht verstanden wird, ist das der falsche Weg.

Andererseits kann es zwischen eingespielten Entwicklern genügen, dass solch ein Zettel mit den Anforderungen ausgetauscht wird.
Um es auf den Punkt zu bringen: Wähle die Sprache, die dein Kunde spricht.

Package Diagramme

UML Package Diagramme bieten eine statische Sicht auf ein System (im Gegensatz zu dynamischen Sichten wie z.B. Sequenzdiagramme). Ein Package kann stellvertretend stehen für:

  • einen Namespace
  • ein Subsystem
  • eine Schicht (Layer)

Mit diesen Bedeutungen eines Packages ist es möglich, die Organisation der Software mit einem UML Package Diagramm zu entwerfen. Dieses bietet eine logische Sicht auf die Architektur, deshalb wird dieser Diagrammtyp häufig beim Vorgehen nach dem 4+1 Modell verwendet.

Nachtrag: Nach der Veröffentlichung habe ich bemerkt, dass bei Wikipedia im Eintrag über das 4+1 Modell das Package-Diagramm nicht explizit bei der logischen Sicht aufgeführt ist, dafür aber bei der Entwicklungssicht (Development view). Es ist aber durchaus so, dass sich ein Package Diagramm hervorragend zur Beschreibung der Schichten eines Systems eignet, und bei dieser Verwendung die logische Sicht beschreibt (vgl. „Applying UML and Patterns“, Craig Larman 2005).

Stereotypen und Tagged Values

Alte Hasen kennen das: Früher erlaubten es die UML-Tools, einfach einen String als Stereotypen zu verwenden, und einen String mit „=“ als Tagged Value.
Dann kam UML2. Tagged Values sind nun Meta-Attribute von Stereotypen. Stereotypen sind nun Meta-Klassen, die Profilen zugeordnet sind.
Metamodell von Profilen
Profile wurden eingeführt, um UML für verschiedene Einsatzzwecke anpassbar zu machen. Sie sind keine Erweiterung von UML, sondern können nur zum Metamodell weitere Einschränkungen definieren.

Um in einem UML-Tool einen eigenen Stereotypen zu verwenden, muss zumindest ein neues Package angelegt werden, in dem für den Stereotyp eine Klasse angelegt wird. Tagged Values sind die Attribute dieser Klasse. Die Verwaltung von Profilen ist sehr Tool-spezifisch, bei einigen Tools muss ein eigenes Projekt für das Profil angelegt werden, bei anderen Tools reicht ein Package aus.

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

Designentscheidungen und Designbewertung

„Es gibt keinen Königsweg“. In der Softwareentwicklung lassen sich die Aufgaben auf mehrere Arten lösen. Welcher Lösungsansatz sich nachher durchsetzt ist eine Designentscheidung. Vor der Designentscheidung steht die Designbewertung (oft werden Entscheidung und Bewertung von unterschiedlichen Personen durchgeführt), diese beschreibt die Vor- und Nachteile der Lösung bezogen auf die Aufgabenstellung.
Die Designbewertung muß sich ggf. auf Annahmen stützen. Die Beantwortung des Kriteriums „Wie gut deckt die Lösung die in diesem Jahr wahrscheinlichen Erweitungen ab und wie lange dauert die Umsetzung?“ beinhaltet neben der technischen Bewertung (also dem Ergebnis) auch Annahmen über die wahrscheinlichen Erweiterungen.
Ist die Designentscheidung getroffen, so muß sie an das Entwicklungsteam kommuniziert werden. Hier bietet sich UML an, falls das Entwicklungsteam UML beherrscht. Ansonsten kann auf Text, Pseudocode oder Codeschnipsel zurückgegriffen werden.
Die Designbewertung kann das Design nicht im leeren Raum betrachten, sondern muss immer die Aufgabenstellung berücksichtigen. Ein Beispiel: Zwei Alternativen, welche ist (ohne Betrachtung der Aufgabe) besser?
Alternative 1

Alternative 2
Früher (direkt nach dem Studium) hätte ich die erste Alternative ohne Betrachtung der Aufgabe als „besser“ bezeichnet, sie „fühlt“ sich besser an. Grund ist hier, dass dieses Modell einige Constraints besitzt, während das zweite Modell ein Tausendfüßler-Rind erlaubt. Aber in der Natur gibt es auch Ausnahmen: Ein Rind mit zwei Köpfen wurde bereits geboren, und ein Rind, das ein Bein verloren hat, ist immer noch ein Rind. Und soll eine Software für einen Schlachthof erstellt werden, hat das zweite Modell einige Vorteile.
Deshalb muss bei der Designbewertung stets auf die zu lösende Aufgabe eingegangen werden.

Exceptions

Exceptions heißen übersetzt „Ausnahmen“. Das bedeutet, dass eine Exception durch eine nicht normale Situation hervorgerufen wird. Für die Definition einer nicht normalen Situation gibt es wiederum verschiedene Ansätze:

  • Der bequeme Ansatz geht nur von „happy path“ aus, alle Abweichungen davon sind Exceptions
  • Der extreme Ansatz kann auf alle Situationen entweder technisch oder fachlich reagieren und benötigt keine Exceptions

Der extreme Ansatz ist in der Praxis nicht möglich, erstens können nicht alle Fehler vorhergesehen werden, und zweitens können bei der Kompensation von Fehlern wiederum Fehler auftreten, somit ergibt sich ein endloses Programm. Der bequeme Ansatz kommt durchaus in der Praxis vor, er bürdet aber alle Verantwortung dem Aufrufer auf und ist somit unbeliebt. Zwischen diesen beiden Extremen liegt der pragmatische Ansatz, der eine praxisgerechte Mischung beider Konzepte ist.

Folgende Regeln helfen mir, einen gesunden Ansatz zu finden:

  • Eine Exception wird nie zur direkten Kontrolle des Programmflusses benutzt
  • Eine Exception bedeutet eine Situation, auf die nicht angemessen reagiert werden kann, das Werfen einer Exception verlagert dann die Reaktionsmöglichkeit in den Aufrufer
  • Aus Sicht des Clients kann eine Exception überall im try-Block eines try-catch-finally Statements auftreten, also kann der Kontrollfluss beim Auftreten der Exception irgendwo im try-Block stoppen und im catch-Block fortfahren. Der catch-Block stellt wieder einen konsistenten Zustand her
  • Jede Exception beinhaltet eine treffende Beschreibung der Ausnahmesituation
  • Exception-Handling wird nicht nachträglich eingefügt, sondern von Anfang an bei der Entwicklung berücksichtigt

Exceptions können nach unterschiedlichen Gesichtspunkten klassifiziert werden. Da für die Komponente, welche die Ausnahme wirft, alle Klassifizierungen „richtig“ sind, ist bei der Wahl der Klassifizierung auf die Bedürfnisse des Aufrufers Rücksicht zu nehmen. Für Klassifizierungsbeispiele siehe folgendes Bild.

Exceptions

Wird eine JEE-Applikation entwickelt, so erhalten die Exceptions eine zusätzliche Semantik bezüglich der Transaktionssteuerung: RuntimeExceptions, die eine ApplicationException-Annotierung besitzen und Checked-Exceptions bedeuten eine Fortsetzung der Transaktion. Fliegen hingegen RuntimeExceptions ohne spezielle Annotierung über EJB-Grenzen, so wird die Transaktion zurückgerollt. Bei der Entwicklung von EJBs ist diese Semantik immer zu berücksichtigen.

Generell gilt: Bei dem Design von Exceptions muss über Kompoententengrenzen hinweg gedacht werden, da die Bedürfnisse und Reaktionsmöglichkeiten der Aufrufers ebenfalls zu berücksichtigen sind.

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.