09.03.2014 Aufrufe

Object Constraint Language (OCL)

Object Constraint Language (OCL)

Object Constraint Language (OCL)

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

© 2004-2007, Rainer Schmidberger, ISTE<br />

<strong>Object</strong> <strong>Constraint</strong><br />

<strong>Language</strong> (<strong>OCL</strong>)<br />

Rainer Schmidberger<br />

rainer.schmidberger@informatik.uni-stuttgart.de<br />

se<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

<strong>OCL</strong><br />

Die <strong>Object</strong> <strong>Constraint</strong> <strong>Language</strong> ist Teil von UML 2.0<br />

<strong>OCL</strong> ist eine formale, prädikatenlogikbasierte Sprache<br />

zur ergänzenden Spezifizierung von UML-Modellen<br />

<strong>OCL</strong> Ausdrücke sind leicht zu lesen (leichter als<br />

beispielsweise die von Z oder die Prädikatenlogik)<br />

<strong>OCL</strong> Ausdrücke sind deklarativ, d.h. sie ändern den<br />

Systemzustand nicht<br />

Dient zur Formulierung von Zusicherungen<br />

Invarianten von Klassen<br />

Vor- und Nachbedingungen von Methoden<br />

Nutzen von <strong>OCL</strong><br />

se<br />

Die UML-Modelle können präziser beschrieben werden<br />

Programmcode kann generiert werden<br />

Folie 104<br />

1


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

<strong>OCL</strong> <strong>Constraint</strong>s (1)<br />

<strong>OCL</strong> constraints werden relativ zu einem Systemzustand<br />

S ausgewertet<br />

<strong>OCL</strong> constraints sind vom Typ Boolean; sie sind wahr<br />

oder falsch bezüglich S<br />

<strong>OCL</strong> constraints beschränken die erlaubten<br />

Systemzustände eines UML Klassendiagramms<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 105<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

<strong>OCL</strong> <strong>Constraint</strong>s (2)<br />

Invarianten:<br />

Eine Invariante I für eine Klasse C ist ein Boolscher <strong>OCL</strong>-<br />

Ausdruck.<br />

Semantik: I gilt in jedem feststellbaren Zustand (snapshot) jeder<br />

Instanz von C.<br />

Vor- und Nachbedingungen:<br />

Vor- und Nachbedingungen (v, n) für eine Operation p ist ein<br />

Paar von Boolschen <strong>OCL</strong>-Ausdrücken.<br />

Semantik: v muss zum Zeitpunkt, wenn p aufgerufen wird, true<br />

sein. n muss zum Zeitpunkt, wenn p terminiert, true sein<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 106<br />

2


Der Kontext<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

Der Kontext legt fest, auf welches Element sich ein <strong>OCL</strong> <strong>Constraint</strong><br />

bezieht.<br />

context [ kontextInstanz : ] typeName<br />

inv: OclAusdruck1<br />

...<br />

inv: OclAusdruckn<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

Beispiel:<br />

se<br />

context Person<br />

inv: self.alter > 0<br />

self (die referenziert per<br />

default auf die Kontext-<br />

Instanz)<br />

Soll bedeuten: zu keinem<br />

Zeitpunkt darf es ein Objekt der<br />

Klasse Person geben, das einen<br />

negativen Wert im Attribut alter<br />

hat<br />

Folie 107<br />

Boolean Operationen<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

Operation<br />

Oder | Und |<br />

Exklusiv Oder<br />

Negation<br />

Notation<br />

a or | and | xor b<br />

not a<br />

Ergebnistyp<br />

Boolean<br />

Boolean<br />

11.01.2007<br />

Vergleich<br />

Ungleichheit<br />

a = b<br />

a b<br />

Boolean<br />

Boolean<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Impliziert (wenn a<br />

true ist, muss auch b<br />

true sein<br />

a implies b<br />

Boolean<br />

Folie 108<br />

3


Integer/Real Operationen<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

Operation<br />

Vergleich<br />

Rechnen<br />

Modulo<br />

Notation<br />

a = b, ab, ab, a=b,<br />

a+b, a-b, a*b, a/b<br />

a.mod(b)<br />

Ergebnistyp<br />

Boolean<br />

Integer/Real<br />

Integer/Real<br />

11.01.2007<br />

Min, Max<br />

a.max(b), a.min(b)<br />

Integer/Real<br />

...<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 109<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

Spezielle <strong>OCL</strong>-Operatoren<br />

oclIsTypeOf (t : OclType) : Boolean<br />

oclIsKindOf (t : OclType) : Boolean<br />

oclInState (s : OclState) : Boolean<br />

Prüfung von Zuständen bei Zustandsautomaten (State D.)<br />

oclIsNew () : Boolean<br />

für Nachbedingungen, prüft, ob Objekte innerhalb einer<br />

Methode neu erzeugt wurden<br />

oclAsType(t :OclType) :instanceof OclType<br />

Beispiel:<br />

se<br />

context Person<br />

inv: self.oclIsTypeOf( Person ) -- ist true<br />

inv: self.oclIsTypeOf( Firma) -- ist false<br />

Folie 110<br />

4


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

<strong>OCL</strong> Kollektionen<br />

Set(Menge), OrderdSet<br />

Bag (Liste)<br />

Sequence (geordnete Liste)<br />

Instanzierung:<br />

als Literal<br />

Set { 1, 2, 4, 42}<br />

Sequence {1..10} entspricht Sequence {1,2,3,4,5,6,7,8,9,10}<br />

durch Navigation<br />

durch Aufruf von Kollektionsmethoden<br />

durch Klasse.allInstances()<br />

se<br />

Folie 111<br />

<strong>OCL</strong> Kollektionen (Auszug)<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Operator<br />

count(objekt)<br />

size<br />

isEmpty<br />

notEmpty<br />

forAll()<br />

exists()<br />

select()<br />

includesAll<br />

(Menge2)<br />

Ergebnistyp<br />

integer<br />

integer<br />

boolean<br />

boolean<br />

boolean<br />

boolean<br />

Menge<br />

boolean<br />

Beschreibung<br />

Anzahl, wie oft das Objekt in der<br />

Kollektion enthalten ist<br />

Anzahl d. Elemente<br />

wahr, wenn Menge leer ist<br />

falsch, wenn Menge leer ist<br />

wahr, wenn für jedes<br />

Element gilt<br />

wahr, wenn für mind.<br />

ein Element gilt<br />

Teilmenge, für die gilt<br />

wahr, wenn alle Elemente der<br />

Menge Menge2 enthalten sind<br />

Folie 112<br />

5


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

<strong>OCL</strong> Kollektionen (2)<br />

se<br />

c->forAll(objekt1, ... Objektn |<br />

)<br />

context Firma<br />

inv:<br />

self.Mitarbeiter->forAll(p1, p2 |<br />

p1 p2 implies p1.Name p2.Name)<br />

c->exists(objekt1, ... Objektn |<br />

)<br />

liefert true falls für<br />

alle Elemente true ist.<br />

liefert true falls für<br />

mindestens eines der<br />

Elemente true ist.<br />

context Firma<br />

inv:<br />

self.Mitarbeiter->exists(p | p.Gehalt > 100000)<br />

Folie 113<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

<strong>OCL</strong> - Beispiel<br />

se<br />

Person<br />

Name<br />

Vorname<br />

Gehalt<br />

Alter<br />

Mitarbeiter<br />

0..*<br />

Arbeitgeber<br />

Firma<br />

Bezeichnung<br />

Die Mitarbeiter sind mind. 16 und max. 65 Jahre alt<br />

Jeder hat ein Gehalt > 0<br />

context Firma<br />

inv:<br />

self.Mitarbeiter->forAll(m | m.Alter>=16 and m.AlterforAll(m | m.Gehalt >= 0)<br />

0..1<br />

Folie 114<br />

6


<strong>OCL</strong> - Beispiel<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

0..*<br />

Mitarbeiter<br />

0..1<br />

Chef<br />

Person<br />

Name<br />

Vorname<br />

Gehalt<br />

Alter<br />

Mitarbeiter<br />

0..*<br />

0..1<br />

Arbeitgeber<br />

Firma<br />

Bezeichnung<br />

11.01.2007<br />

Der Chef verdient mehr als sein Mitarbeiter<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

context Person<br />

inv:<br />

self.Chef->notEmpty() implies<br />

self.Chef.Gehalt > self.Gehalt<br />

Folie 115<br />

<strong>OCL</strong> - Beispiel<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

0..*<br />

Mitarbeiter<br />

0..1<br />

Chef<br />

Person<br />

Name<br />

Vorname<br />

Gehalt<br />

Alter<br />

Mitarbeiter<br />

0..*<br />

0..1<br />

Arbeitgeber<br />

Firma<br />

Bezeichnung<br />

11.01.2007<br />

Der Chef arbeitet bei der selben Firma wie sein Mitarbeiter<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

context Person<br />

inv:<br />

self.Chef->notEmpty() implies<br />

self.Chef.Arbeitgeber = self.Arbeitgeber<br />

Folie 116<br />

7


<strong>OCL</strong> - Beispiel<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

0..*<br />

Mitarbeiter<br />

0..1<br />

Chef<br />

Person<br />

Name<br />

Vorname<br />

Gehalt<br />

Alter<br />

Mitarbeiter<br />

0..*<br />

0..1<br />

Arbeitgeber<br />

Firma<br />

Bezeichnung<br />

11.01.2007<br />

Es gibt mindestens einen „Oberchef“<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

context Firma<br />

inv:<br />

self.Mitarbeiter->select(Chef->isEmpty())->size >= 1<br />

Folie 117<br />

Vor- und Nachbedingungen<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Person<br />

Name<br />

Gehalt : Real<br />

Mitarbeiter<br />

0..*<br />

0..1<br />

Arbeitgeber<br />

Firma<br />

Bezeichnung<br />

istPleite : Boolean<br />

einstellen(p : Person)<br />

context Firma::einstellen(p : Person)<br />

pre:<br />

not self.istPleite and -- Firma ist nicht pleite<br />

p.Arbeitgeber->isEmpty() -- Person ist nicht bereits<br />

-- anderswo beschäftigt<br />

post:<br />

p.Arbeitgeber = self and -- jetzt eingestellt<br />

p.Gehalt > p.Gehalt@pre -- Stellenwechsel mit<br />

-- Gehaltserhöhung<br />

Folie 118<br />

8


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

<strong>OCL</strong> Messages<br />

Um auszudrücken, dass eine „Botschaft“ versendet<br />

wurde, dient der hasSent (‘^’) Operator:<br />

context Firma::einstellen(p : Person)<br />

post: p^setArbeitgeber(self)<br />

Bei unspezifizierten Parametern:<br />

context Subject::hasChanged()<br />

post: observer^update(? : Integer, ? : Integer))<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

Die Menge der Aufrufe einer Methode an einen<br />

Empfänger wird über ^^ ausgedrückt<br />

se<br />

Folie 119<br />

<strong>OCL</strong> Werkzeuge<br />

11.01.2007<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 120<br />

9


11.01.2007<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

<strong>OCL</strong> Literatur<br />

http://www.omg.org/technology/documents/modeling<br />

_spec_catalog.htm<br />

Jos Warmer, Anneke Kleppe, „The <strong>Object</strong> <strong>Constraint</strong><br />

<strong>Language</strong>“, second edition, Addison-Wesley, 2003.<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 121<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

Übung<br />

se<br />

+assistenzTrainer<br />

0..*<br />

Trainer<br />

Verein<br />

vereinsName : String<br />

1<br />

+arbeitgeber<br />

+mitarbeiter 11..*<br />

Spieler<br />

istVerletzt : Boolean<br />

istTorwart : Boolean<br />

1<br />

+chefTrainer<br />

+torwart<br />

1<br />

+feldspieler<br />

10<br />

Spiel<br />

austragungsort : String<br />

austragungsDatum : Date<br />

0..1<br />

Aufstellung<br />

auswechseln(spielerRein : Spieler, spielerRaus : Spieler)<br />

0..1<br />

+gast<br />

+heim<br />

Folie 122<br />

10


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Aufgabe<br />

Jeder Verein hat mindestens einen Cheftrainer<br />

Kein Spieler einer Aufstellung ist verletzt<br />

Alle Spieler einer Aufstellung arbeiten beim selben<br />

Verein<br />

Vor und Nachbedingung<br />

auswechseln<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 123<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

Übung a:<br />

Jeder Verein hat mindestens einen Cheftrainer<br />

context Verein<br />

inv: not self.chefTrainer->isEmpty()<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

11.01.2007<br />

se<br />

Folie 124<br />

11


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Übung b:<br />

Kein Spieler der Aufstellung ist verletzt<br />

context Aufstellung<br />

inv: self.feldSpieler->Select(istVerletzt)->isempty()<br />

inv: not self.torwart.istVerletzt<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 125<br />

© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Übung c:<br />

Alle Spieler einer Aufstellung arbeiten beim selben Verein<br />

context Aufstellung<br />

inv: self.feldSpieler->forAll(s1, s2 |<br />

s1.arbeitgeber = s2.arbeitgeber)<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

Folie 126<br />

12


© 2004-2007, Rainer Schmidberger, ISTE<br />

11.01.2007<br />

Übung d:<br />

Auswechslung<br />

context Aufstellung::auswechseln(spielerRein : Spieler,<br />

spielerRaus : Spieler)<br />

pre:<br />

self.feldspieler->exists(spielerRaus) and<br />

not self.feldspieler->exists(spielerRein) and<br />

not spielerRein.istVerletzt<br />

Programmentwicklung,<br />

Vorlesungsskript UML<br />

se<br />

post:<br />

not self.feldspieler->exists(spielerRaus) and<br />

self.feldspieler->exists(spielerRein)<br />

Folie 127<br />

13

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!