3. Die Lösung
Bild 3 zeigt ein Klassendiagramm, das dieselben Informationen enthält
wie Bild 1. Die bessere Übersichtlichkeit und damit Benutzbarkeit verdankt das
Diagramm einer Reihe von Methoden, die über die UML-Notation hinausgehen. Mit
einer Ausnahme folgen diese Erweiterungen dem Prinzip der geringsten Überraschung
und sollten mit einem Blick intuitiv erfaßt werden können.
Hier eine Auflistung der Methoden:
- Die Nutzbarkeit beginnt mit der Größe. Alle Diagramme sind auf
das DIN A4 Format ausgerichtet. Das hat nicht nur den Sinn den Ausdruck
auf Papier zu ermöglichen, sondern hat auch mit dem menschlichen
Wahrnehmungsapparat zu tun. Größere Flächen können vom menschlichen Auge nicht
mehr gleichzeitig erfaßt werden. Dagegen wirkt das Diagramm aus Bild 3 angenehm
handlich.
- Vererbungsbeziehungen werden durch Linien dargestellt, die den Obertyp mit dem
Untertyp verbinden. Der Obertyp befindet sich dabei physikalisch immer links oder
oberhalb des Untertypen. Dementsprechend verlassen die Linien den Obertypen immer
rechts oder unten und enden am Untertypen immer links oder oben.
-
Zur Unterscheidung der Oberklasse-Unterklasse-Beziehung von den Vererbungsbeziehungen
an denen Interfaces beteiligt sind, werden dicke dunkelblaue rechtwinklig
verlaufende Linien verwendet. Die Interface-Beziehungen werden mit dünnen hellblauen
schräg verlaufenden Linien dargestellt.
- Auf eine Darstellung von Assoziationen mit Linien wird verzichtet.
Dies liegt in der Tatsache begründet, daß die Anzahl der Assoziationen bei Klassen
meistens viel zu groß ist, um noch übersichtlich dargestellt werden zu können. So
hat zum Beispiel die Klasse java.awt.Component mehr als 50 getter-Methoden,
während die Klasse java.awt.event.KeyEvent fast 200 Felder hat. Auch wenn es sich
hierbei um Extremfälle handeln mag, wären die für gewöhnlich zu erwartenden 10-20
Assoziationen immer noch zu viel. Assoziationen werden auf eine andere Art und
Weise durch die noch zu erwähnende Sonderrolle von Accessor-Methoden
hervorgehoben.
- Der Inhalt einer Klasse oder eines Interfaces wird in den 4 farblich abgegrenzten
Bereichen:
- Titelzeile,
- Konstruktoren,
- Methoden und
- Felder
dargestellt. Sollen wie
in Bild 4 nur die Vererbungsbeziehungen einer Klasse dargestellt werden, so
können die unteren 3 Bereiche auch unterdrückt werden - die sogenannte
kollabierte Darstellung.
- Die Namen von abstrakten Klassen und Interfaces werden
ebenso wie die Namen von abstrakten Methoden kursiv geschrieben. In der nicht
kollabierten Darstellung haben abstrakte Klassen und Interfaces außerdem keinen
Rand.
- Zur deutlichen Unterscheidung werden Klassen mit einem dunkelblauen Hintergrund
und Interfaces mit einem hellblauen Hintergrund in der Titelzeile versehen.
- Jedes Diagramm hat ein Haupt-Package. Klassen aus anderen Packages enthalten in der
Titelzeile den Packagenamen, der zur Absetzung vom Klassennamen in kleinerer
Schrift dargestellt ist. Bei inneren Klassen wird auch der Name der äußeren Klasse
aufgeführt.
- Jedes Package ist durch ein eigenes Icon repräsentiert. Dabei ist nicht davon
auszugehen, daß die Zuordnung von Icon zu Package wirklich intuitiv zu erfassen
ist. Vielmehr dienen Icons dazu Packages besser voneinander zu unterscheiden und
häufig verwendete Packages rascher zu identifizieren.
- Innerhalb einer Klasse unterliegen die Namen
- für Typen (blau),
- für Methoden (rot) und
- für Konstanten (grün)
einer Farbkodierung. Die Variablennamen von Argumenten sowie Klammer und
Trennzeichen sind schwarz.
- Das Vorhandensein von Exceptions wird durch ein fettes
rotes Blitzsymbol angedeutet. Sind alle Ausnahmen vom Typ java.lang.Error oder
java.lang.RuntimeException so wird nur ein dünnes blaues Blitzsymbol verwendet.
- Eines der wesentlichen Anliegen des Klassen-Dokumentationsprojektes ist die Menge
der verfügbaren Informationen so stark zu komprimieren, daß die Informationen
übersichtlich und damit handhabar werden. Deswegen werden nur die public und
protected Methoden einer Klasse gezeigt. Methoden mit package- oder private-Access
können ausserhalb des Packages eh nicht benutzt werden. Darüber hinaus wird in den
Diagrammen auch auf Felder mit protected-Access verzichtet. Die korrekte
objektorientierte Programmierung sollte aus Gründen der Kapselung sowieso auf
öffentliche Felder verzichten. Leider spielen aber Konstanten (static final
Felder) und public Felder eine zu wichtige Rolle in den bestehenden Klassen
um auch sie in der Darstellung zu unterdrücken.
- Protected-Access wird wie in UML üblich durch ein "#"-Symbol angezeigt.
Normalerweise verlangt UML auch die Kennzeichnung von public-Elementen durch das
"+"-Symbol. Für einen besseren visuellen Kontrast wird hier auf das "+"
verzichtet.
- Statische Methoden und Felder (außer Konstanten) sind fett dargestellt. Man
beachte, daß auch Konstuktoren fett sind, da sie immer statisch sind.
- Alle Argumente einer Methode oder eines Konstruktors werden immer vollständig
aufgeführt. Sollte dazu die verfügbare Breite nicht ausreichen, wird ein Umbruch
in die darauffolgende Zeile vorgenommen.
- Die Methoden sind die wichtigsten Elemente einer Klasse, die zudem auch noch in
großer Zahl daherkommen. Statt alle Methoden einfach untereinander aufzureihen,
erfolgt eine Einteilung in die Kategorien:
- Static,
- Accessor,
- Collector,
- Event,
- Object,
- Sonstige public und
- Sonstige protected.
Innerhalb einer Kategorie werden die Methoden alphabetisch aufgezählt. Die
Einteilung wird an Hand des Namens der Methode durchgeführt. So gilt in Java die
Konvention, daß alle Accessor-Methoden mit "get", "set", "is" oder "put" beginnen.
- Eine sehr effektive Informationskompression wird durch das Zusammenfassen von
getter- mit setter-Methoden in einer Zeile erreicht. So werden die beiden Zeilen
public void setName (String name) und
public String getName ()
zu einer Zeile
public String get / setName ()
zusammengefaßt.
Man beachte, daß hierfür der Rückgabetyp der getter-Methode identisch mit dem
ersten oder letzten Argument der Setter-Methode sein muß und das die Exceptions
und die Reihenfolge und Typen der anderen Argumente übereinstimmen müßen.
Ähnlich Zusammenfassungen gelten für die Kombinationen "is"-"set" und "add"-"remove".
- Eine äußerst effektive Art Diagramme zu vereinfachen, besteht darin Methoden, die
bereits in der Oberklasse dargestellt wurden, nicht ein zweites Mal in der
Unterklasse aufzuführen, auch wenn diese Methoden in der Unterklasse überschrieben
werden. Auch hierzu muß natürlich der Typ und die Reihenfolge
der Argumente identisch sein. Ein Betrachter des Diagramms wird auf
diese Weise nur über die neuen Verträge der Unterklasse informiert.
Statische Methoden und Felder werden nie verborgen.
Das Verbergen der geerbten Verträge ist ungewöhnlich genug,
um jedes Diagramm mit dem expliziten Hinweis:
"Methods declared in supertypes are hidden in subtypes."
auszustatten.
Für die Anwendung dieser Regelung gilt die Voraussetzung, daß der Supertyp im Diagramm
auch aufgeführt sein muß. Wenn es der Platz erlaubt, sollte der Supertyp zudem
nicht kollabiert dargestellt sein.
Bild 5 zeigt am Beispiel des IO-Frameworks
die Unterschiede, die durch Anwendung dieser Regel resultieren.
Das untere Diagramm führt bei jeder Klasse nur die neuen Methoden auf
und ist wesentlich kompakter.
Das angeblich so komplizierte IO-Framework ist auf diese Weise
sehr überschaubar geworden.
Bild 5: Klassendiagramme ohne (oben) und mit (unten) Verbergen der geerbten Verträge
|
Über den Aspekt der Diagrammgestaltung
hinausgehend, gibt es noch eine Reihe von weiteren Umständen zu
berücksichtigen, die den Gebrauchswert der Diagramme erhöhen können. So sollten den
Diagrammen erklärende Texte, Tabellen und Grafiken hinzugefügt werden. Bei einer
größeren Anzahl von Diagrammen ist auch die Organisationstruktur entscheidend. Was
nützt das schönste Diagramm, wenn es nicht gefunden wird. Darüber hinaus können Diagramme
Links enthalten, die auf Seiten mit weiteren Informationen verweisen. Hier
kommt es auf das Präsentationsmedium an.
Die Möglichkeiten der attraktiven Gestaltung sind damit bei weitem noch nicht erschöpft.
Hier habe ich nur die Methoden aufgezählt, die ich zum einen realisieren konnte und
zum anderen auch in der Praxis auf ihre Tauglichkeit testen konnte.
Ich hoffe das Interesse an diesem Gebiet ist groß genug um weitere Forschungen
zu ermöglichen. Über eine
Rückmeldung
würde ich mich sehr freuen.
*Markus Falkhausen*
Literatur
[1] "Design Patterns", Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides,
Addison-Wesley 1995.
[2] "Java in a Nutshell", David Flanagan, O'Reilly & Associates 1996-2002.
[3] "TogetherJ UML diagram tool", www.togethersoft.com.
[4] "The Non-Designers Design Book", Robin Williams, Peachpit Press 1994.
[5] "Drawing Dynamic Trees", Sven Moen, IEEE Software, July 1990, Seite 21-28.
[6] "Dilbert", www.dilbert.com.
2. Die Ursachen
|