Abbildung von UML nach Java Klassendiagramm - Business ...
Abbildung von UML nach Java Klassendiagramm - Business ...
Abbildung von UML nach Java Klassendiagramm - Business ...
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Abbildung</strong> <strong>von</strong> <strong>UML</strong> <strong>nach</strong> <strong>Java</strong><br />
Beispiele<br />
<strong>Klassendiagramm</strong><br />
Assoziationen<br />
Generalisierung (Mehrfachvererbung)<br />
Kollaboration (Patterns)<br />
Zustandsdiagramm<br />
Interaktionsdiagramm<br />
Zusammenfassung und Ausblick<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
<strong>Klassendiagramm</strong><br />
Assoziationen - Optimierungen im Detailentwurf<br />
<strong>Abbildung</strong> <strong>von</strong> Assoziationen / Aggregationen<br />
auf OO Programmiersprache bzw. DB<br />
Realisierung <strong>von</strong> Beziehungen in Interaktionsdiagrammen<br />
festlegen (global, lokal, etc.) und<br />
entsprechende Änderung des Klassenmodells<br />
vornehmen<br />
Navigation - Zugriffspfade über redundante<br />
Assoziationen optimieren<br />
abgeleitete Attribute und Assoziationen<br />
materialisieren<br />
Sichtbarkeiten festlegen<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
1<br />
2
<strong>Klassendiagramm</strong><br />
Assoziationen - Bidirektionale 1:1-Assoziation<br />
-attrX: AXType<br />
+opX ()<br />
X<br />
rX<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
X<br />
-attrX: AXType<br />
-rY: Y<br />
+opX ()<br />
+X (Y y)<br />
+assoc (Y y)<br />
+assoc (): Y {query}<br />
//Assoziationsverwaltung<br />
// Assoziationsverwaltung<br />
private Y rY; rY<br />
public X(Y y) {<br />
assoc(y);<br />
...<br />
}<br />
public void assoc(Y y) {<br />
if (rY ( rY != y) {<br />
rY = y;<br />
y.assoc(this);<br />
}<br />
}<br />
public Y assoc() {<br />
return rY; rY<br />
}<br />
© 2005 } <strong>Business</strong> Informatics Group, TU Wien<br />
assoc<br />
rY<br />
1 1<br />
<strong>Klassendiagramm</strong><br />
Assoziationen - Bidirektionale 1:1-Assoziation<br />
class X {<br />
private AXType attrX; attrX<br />
public void opX() opX()<br />
{...}<br />
-attrY: AYType<br />
+opY ()<br />
Y<br />
rX<br />
assoc<br />
rY<br />
-attrY: AYTyp<br />
1 1<br />
-rX: X<br />
Y<br />
+opY ()<br />
+Y (X x)<br />
+Y ()<br />
+assoc (X x)<br />
+assoc (): X {query}<br />
class Y {<br />
private AYType attrY; attrY<br />
public void opY() opY()<br />
{...}<br />
//Assoziationsverwaltung<br />
// Assoziationsverwaltung<br />
private X rX; rX<br />
public Y(X x) {<br />
assoc(x);<br />
...<br />
}<br />
public void assoc(X x) {<br />
if (rX ( rX != x) {<br />
rX = x;<br />
x.assoc(this);<br />
}<br />
}<br />
public X assoc() {<br />
return rX; rX<br />
}<br />
public Y() { ... }<br />
}<br />
3<br />
4
<strong>Klassendiagramm</strong><br />
Assoziationen - Unidirektionale ?:1-Assoziation<br />
X<br />
-attrX: AXType<br />
-rY: Y<br />
+opX ()<br />
+X (Y y)<br />
+assoc (Y y)<br />
+assoc (): Y {query}<br />
rX<br />
class X {<br />
private Y rY; rY<br />
public X(Y y) {<br />
assoc(y);<br />
...<br />
}<br />
public void assoc(Y y) {<br />
rY = y;<br />
}<br />
public Y assoc() {<br />
return rY; rY<br />
}<br />
}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
X<br />
-attrX: AXType<br />
-rY: Y<br />
+opX ()<br />
+X (Y y)<br />
+assoc (Y y)<br />
+assoc (): Y<br />
{query}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
assoc<br />
rY<br />
(egal egal) 1<br />
-attrY: AYType<br />
+opY ()<br />
Y<br />
class Y {<br />
// keine Änderungen<br />
// notwendig<br />
}<br />
Viel einfacher –<br />
bidirektionale Assoziationen<br />
möglichst vermeiden!<br />
<strong>Klassendiagramm</strong><br />
Assoziationen - Navigation und Kopplung (1/2)<br />
rX<br />
assoc<br />
1 1<br />
Y<br />
-attrY: AYType<br />
-rX: X<br />
+opY ()<br />
+Y (X x)<br />
+Y ()<br />
+assoc (X x)<br />
+assoc (): X<br />
{query}<br />
Zugriff eines Klienten <strong>von</strong> X auf Eigenschaften des<br />
assoziierten Y-Objekts:<br />
void klientenMethode (X einX) {<br />
...<br />
einX.assoc().opY(); // Kopplung an Y!<br />
}<br />
Koppelt den Klienten nicht nur an X, sondern auch an Y!<br />
rY<br />
5<br />
6
<strong>Klassendiagramm</strong><br />
Assoziationen - Navigation und Kopplung (2/2)<br />
»Demeter-Gesetz«:<br />
Assoziation nicht öffentlich sichtbar machen<br />
Notwendige Y-Operation durch X anbieten<br />
X<br />
-attrX: AXType<br />
-rY: Y<br />
+opX ()<br />
+X (Y y)<br />
-assoc (Y y)<br />
+opY ()<br />
rX<br />
void klientenMethode (X einX) {<br />
...<br />
einX.opY();<br />
}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
assoc<br />
rY<br />
1 1<br />
rY.opY() rY.opY()<br />
<strong>Klassendiagramm</strong><br />
Assoziationen - Bidirektionale 1:n-Assoziation (1/2)<br />
-rY[0..k]:Y<br />
rY[0..k]:Y<br />
-nY:int nY:int<br />
X<br />
rX<br />
1<br />
assoc<br />
rY<br />
0..k<br />
Y<br />
«refine» «refine»<br />
X<br />
+assoc(y:Y assoc(y:Y)<br />
+rmAssoc(y:Y<br />
rmAssoc(y:Y)<br />
+nAssoc():int{query<br />
nAssoc():int{query}<br />
+assoc(i:int):Y{query<br />
assoc(i:int):Y{query}<br />
+findAssoc(y:Y):int{query<br />
findAssoc(y:Y):int{query}<br />
Obergrenze<br />
k ist fest<br />
Y<br />
-attrY: AYType<br />
-rX: X<br />
+opY ()<br />
+Y (X x)<br />
+Y ()<br />
-assoc (X x)<br />
+opX ()<br />
-rX:X rX:X<br />
Y<br />
+Y(x:X)<br />
+assoc(x:X<br />
assoc(x:X)<br />
+assoc():X{query<br />
assoc():X{query}<br />
7<br />
8
<strong>Klassendiagramm</strong><br />
Assoziationen - Bidirektionale 1:n-Assoziation (2/2)<br />
class X {<br />
./.<br />
private Y[] rY = new Y[k]; Y[ ];<br />
private int nY = 0;<br />
public void assoc(Y y) {<br />
public int nAssoc () {<br />
if (findAssoc(y)= 0) {<br />
for (i=0; i
<strong>Klassendiagramm</strong><br />
Assoziationen - Iteration (2/3)<br />
-rY[0..k]:Y<br />
rY[0..k]:Y<br />
-nY:int nY:int<br />
rX<br />
assoc<br />
rY<br />
X Y<br />
1<br />
0..k<br />
«refine» «refine»<br />
X<br />
+assoc(y:Y assoc(y:Y)<br />
+rmAssoc(y:Y<br />
rmAssoc(y:Y)<br />
+nAssoc():int{query<br />
nAssoc():int{query}<br />
+assoc():Enumeration{query<br />
assoc():Enumeration{query}<br />
+findAssoc(y:Y):int{query<br />
findAssoc(y:Y):int{query}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
base<br />
1<br />
Enumeration<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
«instantiate»<br />
<strong>Klassendiagramm</strong><br />
Assoziationen - Iteration (3/3)<br />
-i:int i:int<br />
*<br />
-rX:X rX:X<br />
Y<br />
+Y(x:X)<br />
+assoc(x:X<br />
assoc(x:X)<br />
+assoc():X{query<br />
assoc():X{query}<br />
«use»<br />
Iter<br />
+Iter(x:X Iter(x:X)<br />
+hasMoreElements():boolean{query<br />
hasMoreElements():boolean{query}<br />
+nextElement():Object<br />
nextElement():Object<br />
class X {<br />
private Y[] rY = new Y[k]; Y[ ]; // k fest<br />
private int nY = 0;<br />
public void assoc(Y y) { ... }<br />
public void rmAssoc (Y y) { ... }<br />
public int nAssoc () { ... }<br />
public int findAssoc(Y y) { ... }<br />
private class Iter implements Enumeration {<br />
private X base;<br />
private int i = 0;<br />
public Iter (X x) { base = x; }<br />
public boolean hasMoreElements() {return i
<strong>Klassendiagramm</strong><br />
Assoziationsklasse (1/3)<br />
a11<br />
x1<br />
x2<br />
value = 3<br />
X<br />
rX<br />
rY<br />
Y<br />
*<br />
*<br />
a12<br />
value = 1<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
a13<br />
value = 4<br />
<strong>Klassendiagramm</strong><br />
Assoziationsklasse (2/3)<br />
Assoc<br />
value:int<br />
a22<br />
value = 1<br />
a23<br />
value = 5<br />
X<br />
rX<br />
*<br />
rY<br />
*<br />
Y<br />
«refine» Assoc<br />
«refine»<br />
-rY:Hashtable<br />
rY:Hashtable<br />
X<br />
+assoc(y:Y assoc(y:Y, , a:Assoc) a:Assoc<br />
+rmAssoc(y:Y<br />
rmAssoc(y:Y)<br />
+nAssoc():int{query<br />
nAssoc():int{query}<br />
+assoc():Enumeration{query<br />
assoc():Enumeration{query}<br />
+findAssoc(y:Y):Assoc{query<br />
findAssoc(y:Y):Assoc{query}<br />
Schlüssel:Y<br />
Wert:A<br />
-rX:Hashtable<br />
rX:Hashtable<br />
Y<br />
y1<br />
y2<br />
y3<br />
13<br />
+assoc(x:X<br />
assoc(x:X, , a:Assoc) a:Assoc<br />
+rmAssoc(x:X<br />
rmAssoc(x:X)<br />
+nAssoc():int{query<br />
nAssoc():int{query}<br />
+assoc():Enumeration{query<br />
assoc():Enumeration{query}<br />
+findAssoc(x:X):Assoc{query<br />
findAssoc(x:X):Assoc{query}<br />
14
<strong>Klassendiagramm</strong><br />
Assoziationsklasse (3/3)<br />
class X {<br />
private Hashtable rY = new Hashtable();<br />
public void assoc(Y y, Assoc a) {<br />
if (findAssoc(y) == null) {<br />
rY.put(y, a);<br />
y.assoc(this, a); // »Gegen-Link« »Gegen Link« mit identem<br />
} // Assoziationsobjekt<br />
} // versehen<br />
public void rmAssoc (Y y){<br />
if (rY.remove(y) != null)<br />
y.rmAssoc(this);<br />
}<br />
public int nAssoc () { return rY.size(); }<br />
public Assoc findAssoc(Y y) { return (Assoc)rY.get(y); }<br />
public Enumeration assoc () { return rY.keys(); }<br />
}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
<strong>Klassendiagramm</strong><br />
Komposition<br />
Komposition bei Sprachen mit Wertsemantik (z.B.<br />
C++):<br />
X<br />
1<br />
rY<br />
k<br />
Y<br />
Wenn nur Referenzsemantik zur Verfügung steht<br />
(<strong>Java</strong>):<br />
Wertsemantik simulieren:<br />
Y stellt Methode clone() zur Verfügung, die Objektkopien<br />
erzeugt<br />
X ruft in den Assoziationsverwaltungsmethoden beim Zugriff<br />
auf die Y-Partner clone() auf<br />
Y-Partner »abschotten« und alle Y-Operationen direkt<br />
durch X anbieten (vgl. »Demeter-konforme« Assoziation)<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
class X {<br />
Y rY[k]; // »eingelagerte« Y-Objekte<br />
Y Objekte<br />
...<br />
};<br />
15<br />
16
<strong>Klassendiagramm</strong><br />
Generalisierung – Mehrfachvererbung (1/3)<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
B1 B2<br />
Bei Simulation <strong>von</strong> Mehrfachvererbung zu<br />
beachten:<br />
Spezifikationsvererbung (»Muss«):<br />
A erbt die nichtprivaten Schnittstellen <strong>von</strong> B1 und B2<br />
Implementationsvererbung (»Soll«):<br />
A erbt die Implementation <strong>von</strong> B1 und B2<br />
(Code-Wiederverwendung)<br />
<strong>Klassendiagramm</strong><br />
Generalisierung – Mehrfachvererbung (2/3)<br />
A<br />
Vorgangsweise bei n-fach-Vererbung:<br />
1x: »echte« Vererbung <strong>von</strong> Basisklasse B1<br />
(n-1)x: simulierte Vererbung durch<br />
Interface-Realisierung (Spezifikationsvererbung)<br />
für die Basisklassen B2 ... Bn sind entsprechende<br />
Interfaces vorzusehen<br />
(im Beispiel B2)<br />
Komposition (»Implementationsvererbung«)<br />
der »ehemaligen« Basisklassen B2 ... Bn<br />
(im Beispiel B2I)<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
17<br />
18
<strong>Klassendiagramm</strong><br />
Generalisierung – Mehrfachvererbung (3/3)<br />
-attrB2 attrB2<br />
-attrB2 attrB2<br />
B2<br />
+opB2()<br />
«refine»<br />
B21<br />
+opB2()<br />
«interface interface»<br />
B2<br />
+opB2()<br />
«refine»<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
1<br />
b2<br />
-attrA attrA<br />
+opA opA() ()<br />
-attrA attrA<br />
A<br />
«refine» «refine»<br />
A<br />
+opA opA() ()<br />
+opB2()<br />
0..1<br />
<strong>Klassendiagramm</strong><br />
Kollaboration - Beispiel „Observer Pattern“<br />
Observer:<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
b2.opB2();<br />
-attrB1 attrB1<br />
B1<br />
+opB1()<br />
-attrB1 attrB1<br />
B1<br />
+opB1()<br />
Ziel ist das automatische Be<strong>nach</strong>richtigen <strong>von</strong> abhängigen<br />
Objekten bei Zustandsänderungen eines Objekts<br />
ermöglicht Konsistenzsicherung bei lose gekoppelten<br />
Objekten<br />
wird hauptsächlich in graphischen Benutzeroberflächen<br />
angewendet<br />
Modellierung in <strong>UML</strong> mittels Kollaboration<br />
Definition: Anwendung:<br />
Observer<br />
subject * observer *<br />
subject<br />
kalender<br />
Aktualisierung:<br />
Observer<br />
19<br />
observer<br />
Kalender Kalenderansicht<br />
20
<strong>Klassendiagramm</strong><br />
Kollaboration – Framework für das Observer Pattern<br />
Subject<br />
addObserver (Observer)<br />
removeObserver (Observer)<br />
notifyObservers()<br />
notifyObservers()<br />
Kalender<br />
kalenderState<br />
getState ()<br />
setState ()<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
observers*<br />
observers<br />
for all o in observers<br />
o->update(this<br />
>update(this); );<br />
subject<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
return kalenderState;<br />
kalenderState<br />
// change state… state<br />
notifyObservers();<br />
notifyObservers();<br />
Observer<br />
update (Subject ( Subject)<br />
Kalenderansicht<br />
ansichtState<br />
update (Subject ( Subject)<br />
ansichtState=subject->getState<br />
ansichtState=subject >getState() ()<br />
<strong>Klassendiagramm</strong><br />
Kollaboration – Variante des Observer Pattern im <strong>Java</strong> API<br />
package java.util;<br />
java.util<br />
interface EventListener {} // A tagging interface that all event<br />
// listener interfaces must extend.<br />
class EventObject {<br />
protected Object source; source;<br />
// The object on which the Event<br />
// initially occurred<br />
}<br />
package java.beans;<br />
java.beans<br />
interface PropertyChangeListener extends EventListener {<br />
void propertyChange(PropertyChangeEvent evt); evt);<br />
// This method gets called when a bound property is changed. changed<br />
}<br />
class PropertyChangeEvent extends EventObject {<br />
private String propertyName; propertyName;<br />
// The property that has changed<br />
private Object oldValue,<br />
oldValue,<br />
newValue; newValue;<br />
// Old and new values of the prop.<br />
}<br />
21<br />
22
<strong>Abbildung</strong> <strong>von</strong> <strong>UML</strong> <strong>nach</strong> <strong>Java</strong><br />
Beispiele<br />
<strong>Klassendiagramm</strong><br />
Assoziationen<br />
Generalisierung (Mehrfachvererbung)<br />
Kollaboration (Patterns)<br />
Zustandsdiagramm<br />
Interaktionsdiagramm<br />
Zusammenfassung und Ausblick<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
Zustandsdiagramm (1/6)<br />
Varianten<br />
Transitionen<br />
Operation codiert Trigger sowie Aktion der<br />
Transitionen (d.h., Zustandsdiagramm spezifiziert<br />
Vor- und Nachbedingungen sowie<br />
zustandsspezifisches Verhalten)<br />
Zustände – mehrere Varianten<br />
Explizites Zustandsattribut beschreibt Zustand,<br />
oder<br />
Invarianten disjunkter Zustände als Prädikate, oder<br />
State-Pattern: Jedem Zustand ein eigenes Objekt<br />
zugeordnet<br />
Folien aus Bernhard Rumpe: Agile Modellierung mit <strong>UML</strong> –<br />
Codegenerierung, Testfälle, Refactoring. Springer-Verlag,<br />
2005<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
23<br />
24
Zustandsdiagramm (2/6)<br />
Disjunkte Invarianten für Zustände<br />
[vorb1]<br />
stimulus() /<br />
aktion1<br />
QuellzustandA<br />
[invarianteA]<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
[vorb2]<br />
stimulus() /<br />
aktion2<br />
QuellzustandB<br />
[invarianteB]<br />
Zielzustand1 Zielzustand2 Zielzustand3<br />
public … stimulus() {<br />
if (invarianteA) {<br />
if (vorb1) {<br />
aktion1;<br />
} else if (vorb2) {<br />
aktion2;<br />
} else {<br />
// Fehlerbehandlung<br />
}<br />
else if (invarianteB) {<br />
…<br />
}}<br />
[vorb3]<br />
stimulus() /<br />
aktion3<br />
Zustandsmaschine<br />
<strong>Java</strong><br />
Zustandsinvarianten und<br />
Vorbedingungen werden zur<br />
Unterscheidung der Transitionen<br />
genutzt<br />
Nachteil: Code „invarianteA“<br />
wird mehrfach eingesetzt (wenn<br />
unterschiedliche Stimuli)<br />
Zustandsdiagramm (3/6)<br />
Auslagerung Zustandsinvarianten in eigene Prädikate<br />
QuellzustandA<br />
[invarianteA]<br />
[vorb1]<br />
stimulus() /<br />
aktion1<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
QuellzustandB<br />
[invarianteB]<br />
Zielzustand1 Zielzustand2<br />
public boolean invQuellzustandA() {<br />
return invarianteA;<br />
}<br />
public boolean invQuellzustandB() {<br />
return invarianteB;<br />
}<br />
public … stimulus() {<br />
if (invQuellzustandA()) {<br />
…<br />
}<br />
[vorb2]<br />
stimulus() /<br />
aktion2<br />
jeder Zustand wird zu<br />
einem Prädikat, das<br />
die Zustandsinvariante<br />
evaluiert<br />
25<br />
Zustandsmaschine<br />
<strong>Java</strong><br />
Vorteil: „invarianteA“ nur einmal<br />
generiert<br />
Nachteil: „invarianteA“ kann komplex<br />
sein und zeitaufwendig zu berechnen<br />
Besser: Zustandsattribut speichert<br />
aktuellen Zustand<br />
26
Zustandsdiagramm (4/6)<br />
Einführung eines Zustandsattributs<br />
[vorb1]<br />
stimulus() /<br />
aktion1<br />
QuellzustandA<br />
[invarianteA]<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
[vorb2]<br />
stimulus() /<br />
aktion2<br />
QuellzustandB<br />
[invarianteB]<br />
Zielzustand1 Zielzustand2 Zielzustand3<br />
private int status;<br />
final static int QUELLZUSTAND_A=1;<br />
final static int QUELLZUSTAND_B=2;<br />
final static int ZIELZUSTAND1=3; …<br />
der Diagrammzustand wird als<br />
Aufzählung codiert<br />
Vorteil: Effizient<br />
Nachteile: evtl. redundante Speicherung,<br />
Konsistenz nicht gesichert:<br />
(status==QUELLZUSTAND_A) impliziert<br />
invarianteA<br />
Zustandsdiagramm (5/6)<br />
Nutzung der Invarianten für Tests<br />
Ausgangsdiagramm wie<br />
auf vorheriger Folie<br />
[vorb1]<br />
stimulus() /<br />
aktion1<br />
QuellzustandA<br />
[invarianteA]<br />
[vorb2]<br />
stimulus() /<br />
aktion2<br />
QuellzustandB<br />
[invarianteB]<br />
Zielzustand1 Zielzustand2 Zielzustand3<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
Zustandsmaschine<br />
[vorb3]<br />
stimulus() /<br />
aktion3<br />
Zustandsinvarianten und<br />
manche Vorbedingungen können<br />
als Zusicherungen zu<br />
Testzwecken eingesetzt werden,<br />
wenn angenommen wird, dass<br />
das Diagramm vollständig ist<br />
[vorb3]<br />
stimulus() /<br />
aktion3<br />
Zustandsmaschine<br />
public … stimulus() {<br />
<strong>Java</strong><br />
switch (status) {<br />
case QUELLZUSTAND_A:<br />
if (vorb1) {<br />
aktion1;<br />
status=ZIELZUSTAND1;<br />
} else if (vorb2) {<br />
aktion2;<br />
status=ZIELZUSTAND2;<br />
} …<br />
break;<br />
case QUELLZUSTAND_B:<br />
…<br />
27<br />
}}<br />
<strong>Java</strong><br />
private int status;<br />
final static int QUELLZUSTAND_A=1;<br />
final static int QUELLZUSTAND_B=2;<br />
final static int ZIELZUSTAND1=3;<br />
…<br />
public … stimulus() {<br />
switch (status) {<br />
case QUELLZUSTAND_A:<br />
assert invarianteA;<br />
if (vorb1) {<br />
aktion1;<br />
status=ZIELZUSTAND1;<br />
} else {<br />
assert vorb2;<br />
aktion2;<br />
status=ZIELZUSTAND2;<br />
} …<br />
break;<br />
case QUELLZUSTAND_B:<br />
}}<br />
…<br />
28
Zustandsdiagramm (6/6)<br />
Entwurfsmuster: State (Gamma et.al. 1994)<br />
Ausgangsdiagramm wie<br />
auf vorheriger Folie<br />
[vorb1]<br />
stimulus() /<br />
aktion1<br />
QuellzustandA<br />
[invarianteA]<br />
[vorb2]<br />
stimulus() /<br />
aktion2<br />
QuellzustandB<br />
[invarianteB]<br />
Zielzustand1 Zielzustand2 Zielzustand3<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
Zustandsmaschine<br />
[vorb3]<br />
stimulus() /<br />
aktion3<br />
Klasse state StateKlasse<br />
stimulus()<br />
setState(StateKlasse k)<br />
<strong>UML</strong><br />
stimulus(Klasse k)<br />
QuellzustandA QuellzustandB<br />
stimulus(Klasse k) stimulus(Klasse k)<br />
<strong>Java</strong><br />
class Klasse {<br />
QuellzustandA quellzustandA = …<br />
Zielzustand1 zielzustand1 = …<br />
public … stimulus() {<br />
state.stimulus(this);<br />
}<br />
Vorteil: das State-Entwurfsmuster<br />
kann für zusätzliche Flexibilität verwendet werden<br />
Nachteil: Oberhead durch zusätzliche Objekte pro Zustand<br />
<strong>Abbildung</strong> <strong>von</strong> <strong>UML</strong> <strong>nach</strong> <strong>Java</strong><br />
Beispiele<br />
<strong>Klassendiagramm</strong><br />
Assoziationen<br />
Generalisierung (Mehrfachvererbung)<br />
Kollaboration (Patterns)<br />
Zustandsdiagramm<br />
Interaktionsdiagramm<br />
Zusammenfassung und Ausblick<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
}<br />
class QuellzustandA {<br />
public … stimulus(Klasse k) {<br />
assert invarianteA;<br />
if (vorb1) {<br />
aktion1´;<br />
k.setState(k.zielzustand1);<br />
} else<br />
…<br />
}}<br />
29<br />
30
Interaktionsdiagramm (1/3)<br />
Verwendungszwecke<br />
Interaktionsdiagramm zeigt mögliche Abläufe<br />
im System<br />
Verwendet zur Spezifikation <strong>von</strong> Testfällen<br />
Ableitung <strong>von</strong> Code für<br />
Testtreiber<br />
Ablaufvalidierung<br />
Folien aus Bernhard Rumpe: Agile Modellierung mit <strong>UML</strong> –<br />
Codegenerierung, Testfälle, Refactoring. Springer-Verlag,<br />
2005<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
Interaktionsdiagramm (2/3)<br />
Interaktionsdiagramm definiert Testtreiber<br />
Eine Lebenslinie im<br />
Interaktionsdiagramm stellt<br />
den Testtreiber dar (oft ein<br />
Klientenobjekt)<br />
„fremder“ Methodenaufruf im<br />
Diagramm wird bei<br />
Codegenerierung für den<br />
Testtreiber ignoriert<br />
class Class { …<br />
public void runTestDiagramm(A a, B b, Type2 args2) {<br />
Type value = a.m1();<br />
a.m2(args2);<br />
b.m3();<br />
}<br />
}<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
t:Class a:A b:B<br />
m1()<br />
m1:value<br />
m2(args2)<br />
m3()<br />
otherMethod()<br />
31<br />
<strong>UML</strong><br />
<strong>Java</strong><br />
32
Interaktionsdiagramm (3/3)<br />
Interaktionsdiagramm zur Validierung<br />
Interaktionsdiagramm beschreibt erlaubte/verbotene Abläufe<br />
Zur Beobachtung des Verhaltens ist eine Instrumentierung<br />
des Codes notwendig (Logging) - z.B. per “Adapter”-Muster<br />
Überprüfung des Logging-Protokolls entsprechend dem Diagr.<br />
class Ainstrumented extends A { …<br />
<strong>Java</strong><br />
public Type method () {<br />
// Protokolliere Methodenaufruf (Objekt, Methode, Argumente)<br />
IDlog.call(this, "method", new Object[]);<br />
Type result;<br />
try { // Eigentlicher Aufruf<br />
result = super.method();<br />
catch (Exception ex) {<br />
// Protokolliere Exception<br />
IDlog.exceptionReturn(this, "method", ex);<br />
throw ex;<br />
}<br />
// Protokolliere Return + Ergebnis<br />
IDlog.normalResult(this, "method", result);<br />
return result; }<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
<strong>Abbildung</strong> <strong>von</strong> <strong>UML</strong> <strong>nach</strong> <strong>Java</strong><br />
Beispiele<br />
<strong>Klassendiagramm</strong><br />
Assoziationen<br />
Generalisierung (Mehrfachvererbung)<br />
Kollaboration (Patterns)<br />
Zustandsdiagramm<br />
Interaktionsdiagramm<br />
Zusammenfassung und Ausblick<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
33<br />
34
Zusammenfassung und Ausblick<br />
<strong>Abbildung</strong> <strong>von</strong> <strong>UML</strong> <strong>nach</strong> <strong>Java</strong><br />
viele unterschiedliche Optionen<br />
Auswahl abhängig <strong>von</strong> benutzten<br />
Programmierrichtlinien, Frameworks, etc.<br />
Automatisierte Codegenerierung<br />
mit <strong>UML</strong>-Werkzeugen<br />
Problem der Anpassung des generierten Codes<br />
Model Engineering / Model Driven Architecture<br />
<strong>UML</strong>-Profile für spezielle Zielplattformen, z.B.<br />
Struts/J2EE, etc.<br />
Code-Generatoren anpassbar und/oder selber zu<br />
entwickeln<br />
Ziel: vollständige Codegenerierung<br />
© 2005 <strong>Business</strong> Informatics Group, TU Wien<br />
35