OCL a integritní omezení Karel Richta Katedra softwarového inženýrství Fakulta informačních technologií České vysoké učení technické v Praze richta@fel.cvut.cz, 2011 Softwarové inženýrství I., BI-SI1 04/2011, Přednáška 9 Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 1/78
Proč OCL? Pomocí diagramů UML nelze popsat všechno proto je součástí specifikace UML i definice OCL. Co je zvláštní na následujícím obrázku? richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 2/78
Jiný příklad: Předměty a zkoušky class Studium bez omez... Student - jméno: string - příjmení: string studuje Předmět - kód: string - název: string si zapsal +z 1 +má Zkouškový termín - datum: Date - místnost: int richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 3/78
Předměty a zkoušky o něco lépe class Příklad Studium s omezením Student - jméno: string - příjmení: string studuje Předmět - kód: string - název: string si zapsal +z 1 Student/studentka si mohou zapsat zkouškový termín pouze z předmětů, které právě studují. {C1} +má Zkouškový termín - datum: Date - místnost: int richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 4/78
OCL -ObjectConstraintLanguage pochází z metodiky Syntropy(IBM) http://en.wikipedia.org/wiki/syntropy je čistě funkcionální (bez vedlejších efektů) není to programovací jazyk -je určen pro vyjádření invariantů - je to specifikační jazyk je silně typovaný (každý výraz OCL má definován typ) má předdefinovanou sadu typů (primitivní typy Integer, Boolean, String, Real, UnlimitedIntegera z nichutvořené kolekce) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 5/78
Jak vypadá zápis v OCL? context <jméno> [inv pre post]: <výraz> klíčové slovo contextslouží pro definici kontextu pro výraz v OCL, např. zápis: context Osoba inv : <výraz> označuje, že uvedený výraz se vztahuje k instancikontextu (třídy) Osoba (na kterou se lze odkazovat klíčovým slovem self) klíčová slova inv, pre, postzastupují stereotypy <<invariant>>, <<precondition>>, <<postcondition>> richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 6/78
Příklad zápisu v OCL context Osoba inv: self.příjem > 10000 tento zápis vyjadřuje, že pro každou instance třídy Osoba, musí mít atribut příjem hodnotu větší než 10000 context x:osoba inv: x.příjem > 10000 označuje totéž context x:osoba inv OK : x.příjem > 10000 zavádí pro toto integritní omezení jméno (OK) Příklad popisu metody: context Osoba::pridej(kolik:Integer):Integer pre : kolik > 100 -- nemá smysl přidávat méně post : result = self.příjem@pre + kolik richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 7/78
Příklad: Předměty a zkoušky class Studium v OCL Student - jméno: string - příjmení: string studuje Předmět - kód: string - název: string si zapsal {C1} «Invariant» {-- Student/studentka si mohou zapsat zkouškový termín pouze z předmětů, které právě studují. inv C1 : is-element(self.si_zapsal.z, studuje)} +z 1 +má Zkouškový termín - datum: Date - místnost: int richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 8/78
EA vygeneruje tabulky, ale integritní omezení ne. richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 9/78
Příklad: Hypotéky Uvažme příklad světa hypoték - ukázka z katalogu požadavků: 1. Každá hypotéka bude vždy pro jednu osobu. 2. Osoba si může vzít několik hypoték. 3. Každou nemovitost vlastní právě jedna osoba. 4. Osoba může vlastnit libovolný počet nemovitostí. 5. Každá hypotéka musí být zajištěna nejméně jednou nemovitostí. 6. Nemovitost může být použita k zajištění více hypoték. richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 10/78
Příklad modelu evidence hypoték class Hypotéky bez omezení Nemovitost - označení: string - hodnota: penize +je_zajištěna 1..* +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba + žádost(peníze, Nemovitost) : boolean +pro 1 +zajišťuje +má_půjčenu Hypotéka - od: datum - do: datum - celková_částka: peníze = 250.000,- - měsíční_splátka: peníze richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 11/78
Příklad: Hypotékyo něco lépe class Hypotéky s omezením Nemovitost - označení: string - hodnota: penize +je_zajištěna 1..* +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba + žádost(peníze, Nemovitost) : boolean +pro 1 «Invariant» {Hypotéka může být zajištěna pouze takovými nemovitostmi, které daná osoba vlastní.} {C1} +zajišťuje +má_půjčenu Hypotéka - od: datum - do: datum - celková_částka: peníze = 250.000,- - měsíční_splátka: peníze richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 12/78
class DDL CASE (EA) vygeneruje tabulky, ale integritní omezení ne. Nemov itost «column» označení: VARCHAR2(50) hodnota: penize *pfk nemovitostid: Integer FK je_majetkem: Integer «PK» + PK_Nemovitost(Integer) «FK» + skládá se z(integer) + FK_je_majetkem(Integer) +PK_Nemovitost (nemovitostid = nemovitostid) «FK» +Nemovitost JoinHypotékaToNemov itost «column» *FK nemovitostid: Integer *FK hypotékaid: Integer +FK_je_majetkem +Hypotéka 1..* (je_majetkem = osobaid) «FK» (hypotékaid = hypotékaid) «FK» +PK_Osoba +PK_Hypotéka 1 Osoba «column» jméno: VARCHAR2(50) příjmení: VARCHAR2(50) příjem: peníze *PK osobaid: Integer «PK» + PK_Osoba(Integer) +PK_Osoba 1 (pro = osobaid) «FK» +FK_pro Hypotéka «column» od: datum do: datum celková_částka: peníze = 250.000,- měsíční_splátka: peníze *PK hypotékaid: Integer FK pro: Integer «FK» + Nemovitost(Integer) + Hypotéka(Integer) «PK» + PK_Hypotéka(Integer) «FK» + FK_pro(Integer) 13 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 13/78
CASE vygenerujesql, aleio ne. DROP TABLE Hypotéka CASCADE CONSTRAINTS;... CREATE TABLE Hypotéka ( od DATE, do DATE, celková_částka NUMBER(12,2) DEFAULT 250.000,-, měsíční_splátka NUMBER(12,2), hypotékaid Integer NOT NULL, pro Integer );... ALTER TABLE Hypotéka ADD CONSTRAINT PK_Hypotéka PRIMARY KEY (hypotékaid);... ALTER TABLE Hypotéka ADD CONSTRAINT FK_pro FOREIGN KEY (pro) REFERENCES Osoba (osobaid);... richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 14/78
Ale mohl by něco vygenerovat V popisu integritního omezení v jazyce OCL je dost informace pro vygenerování integritního omezení např. pro SQL: ALTER TABLE JoinHypotékaToNemovitost ADD CONSTRAINT C2 CHECK ( /* -- Hypotéky osoby mohou být zajištěny pouze nemovitostmi, které tato osoba vlastní. */ ); context inv: self.je_zajištěna.je_majetkem = self.pro nemovitostid.je_majetkem = hypotékaid.pro richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 15/78
Kdy použít OCL? pro vyjádření integritních omezení v datovém modelu (diagramu tříd) pro vyjádření typových omezení při definici stereotypů pro popis vstupních a výstupních podmínek operací, nebo pro popis operací (metod) ve tvaru: operace(x1,, xn) = výraz kde výrazmůže obsahovat x1,, xn jako navigační jazyk richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 16/78
self.příjem Výrazy v OCL hodnota vlastnosti objektu o kterém v daném kontextu mluvíme v tomtopřípadě se jedná o atribut a hodnotu typu peníze x.vlastní hodnota vlastnosti objektu o kterém v daném kontextu mluvíme v tomtopřípadě se jedná o vztah a hodnotu typu kolekce nemovitostí (případně prázdná) class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* Nemovitost se zde chápe jako + žádost(peníze, Nemovitost) : boolean +pro 1 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 17/78
Příklad použití OCL I. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +ow ner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Kolik osob může vlastnit auto? Vlastníkem auta může být osoba, které je alespoň 18 let? context Car inv: self.owner.age >= 18 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 18/78
Příklad použití OCLII. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +ow ner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Co znamená podmínka? context Person inv: self.age >= 18 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 19/78
Příklad modelu evidence hypoték class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. + žádost(peníze, Nemovitost) : boolean +pro 1 +zajišťuje 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze +má_půjčenu richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 20/78
OCL lze použít pro navigaci class Příklad modelu pro hypotéky skládá se z 1 Chceme označit Nemov itost měsíční splátky +vlastní - označení: string hypoték osoby Q: - hodnota: penize +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba Q.má_půjčenu.měsíční_splátka +je_zajištěna 1..* Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. (je to množina údajů výsledek je typu Bag(peníze) ) + žádost(peníze, Nemovitost) : boolean +pro 1 +zajišťuje 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze +má_půjčenu richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 21/78
Integritní omezení v OCL class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* +zajišťuje Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze + žádost(peníze, Nemovitost) : boolean +pro 1 Hypotéka musí být zajištěna nemovitostí, jejíž cena není menší než celková zapůjčená částka (pokud je zajištěna +má_půjčenu jednou nemovitostí). context Hypotéka inv : self.celková_částka <= self.je_zajištěna.hodnota richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 22/78
Typy v OCL předefinované primitivní typy (s obvyklými operacemi): Integer Boolean String Real UnlimitedInteger konstruktory: Collection, Set, Bag, Sequence s operátory: collect, select, reject, forall, exists, iterate, include, count, union, intersect, isempty, notempty, isunique,... richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 23/78
Primitivní typy Typ Boolean Integer Operace and, or, xor, not, implies, if-then-else *, +, -, /, abs(), div(integer), mod(integer), min(integer), max(integer) Real String *, +, -, /, abs(), floor(), round(), max(real), min(real) size(), concat(string), toupper(), tolower(), substring(integer, Integer) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 24/78
Operace s primitivními typy size() : Integer (počet znaků v řetězci self) substring(lower : Integer, upper : Integer) : String (podřetězec self začínající na pozici lower a končící na pozici upper. Pozice se počítají od 1 do self.size(). pre: 1 <= lower pre: lower <= upper pre: upper <= self.size() concat(s : String) : String (spojení řetězců self a s) post: result.size() = self.size() + s.size() post: result.substring(1, self.size() ) = self post: result.substring(self.size() + 1, result.size() ) = s richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 25/78
Výčtové typy context Person inv: gender = Gender::male richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 26/78
Příklad použití OCLIII. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ow nership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Všechna vozidla osob jsou černá: context Person inv: self.fleet -> forall(v v.colour = Colour::black) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 27/78
Výrazy v OCL (pokr.) x.vlastní -> isempty() test, zda hodnota typu kolekce nemovitostí je prázdná x.vlastní.hodnota kolekce hodnot typu peníze představující cenu nemovitostí, které objekt x vlastní x.vlastní.hodnota -> sum() cena nemovitostí, které objekt x vlastní, spočítaná jako součet hodnot jednotlivých nemovitostí class Pøíklad modelu pro hypotéky skládá se z 1 Nemovitost - oznaèení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - pøíjmení: string - pøíjem: peníze Osoba +je_zajištìna 1..* + žádost(peníze, Nemovitost) : boolean Nemovitost se zde chápe jako richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 28/78 jednotka vlatnictví. Pokud nějakou +pro 1
Vytváření kolekcí Set {2, 4, 1, 5, 7, 13, 11, 17 } OrderedSet {1, 2, 3, 5, 7, 11, 13, 17 } Sequence {1, 2, 3, 5, 7, 11, 13, 17 } Bag {1, 2, 3, 2, 1} richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 29/78
Pro všechny objekty jsou definovány metody: Typ Operace oclistypeof(t : OclType) : Boolean ocliskindof(t : OclType) : Boolean oclinstate(s : OclState) : Boolean oclisnew() : Boolean oclastype(t : OclType) : instance of OclType richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 30/78
Kolekce Typ Collection Operace ->size(), ->includes(object), ->includesall(collection), ->excludes(object), ->excludesall(collection), ->count(object), ->isempty(), ->notempty(), ->sum(), ->exists(expression), ->forall(expression), ->isunique(expression), ->sortedby(expression), ->iterate(expression), ->any(expression), ->one(expression) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 31/78
Příklad použití OCLIV. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +ow ner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Nikdo nemůže vlastnit více než 3 vozidla context Person inv: self.fleet -> size <= 3 nebo změníme násobnost v diagramu to je ale statické, nemůže se to dynamicky měnit. richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 32/78
Kolekce typu Set Typ Collection::Set Operace ->union(set), ->union(bag), ->intersection(set), ->intersection(bag), ->including(object), ->excluding(object), ->symmetricdifference(set), ->select(expression), ->reject(expression), ->collect(expression), ->count(object), ->assequence(), ->asbag() richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 33/78
Kolekce typu Bag Typ Collection::Bag Operace ->union(bag), ->union(set), ->intersection(bag), ->intersection(set), ->including(object), ->excluding(object), ->symmetricdifference(set), ->select(expression), ->reject(expression), ->collect(expression), ->count(object), ->assequence(), ->asset() richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 34/78
Kolekce typu Sequence Typ Collection::Sequence Operace ->union(bag), ->union(set), ->intersection(bag), ->intersection(set), ->including(object), ->excluding(object), ->symmetricdifference(set), ->select(expression), ->reject(expression), ->collect(expression), ->count(object), ->assequence(), ->asset() richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 35/78
Přesnější vyjádření IO class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* + žádost(peníze, Nemovitost) : boolean Hypotéka musí být zajištěna +pro 1 Nemovitost se zde chápe jako nemovitostmi, jejichž součet jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí cen není menší než celková se na samostatné části dle podílu vlastníků. zapůjčená částka. +zajišťuje 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze +má_půjčenu context Hypotéka inv : self. celková_částka <= self. je_zajištěna.hodnota -> sum() Y36SIN - Jazyk OCL richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 36/78 36
A obráceně class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* +zajišťuje Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze + žádost(peníze, Nemovitost) : boolean +má_půjčenu +pro 1 Nemovitost může zajišťovat pouze tolik hypoték, jejichž součet celkových částek není větší, než cena nemovitosti. context Nemovitost inv : self.zajišťuje.celková_částka -> sum() <= self.hodnota Richta: NSWI041 - Jazyk OCL 37 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 37/78
object Hypotéky bez hranic Důležitá podmínka class Příklad modelu pro hypotéky H-123 :Hypotéka Karlštejn :Nemovitost pro Josef :Osoba zajištěna? vlastní Bouda :Nemovitost skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* +zajišťuje Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze + žádost(peníze, Nemovitost) : boolean +má_půjčenu +pro 1 Hypotéky osoby mohou být zajištěny pouze nemovitostmi, které tato osoba vlastní. context Hypotéka inv : self.je_zajištěna.je_majetkem = self.pro Richta: NSWI041 - Jazyk OCL 38 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 38/78
Vlastnosti operací v OCL class Příklad modelu pro hypotéky skládá se z 1 Nemov itost +vlastní - označení: string Osoby - mohou hodnota: penize žádat o hypotéky, pokud suma +je_zajištěna 1..* měsíčních splátek osoby nepřesáhne 30% příjmu osoby. +je_majetkem Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. 1 - jméno: string - příjmení: string - příjem: peníze Osoba + žádost(peníze, Nemovitost) : boolean +pro 1 +zajišťuje 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze +má_půjčenu context Osoba::žádost(částka:peníze,zajištění:Nemovitost) pre : (self.má_půjčenu.měsíční_splátka -> sum()) + částka/počet_splátek <= self.příjem * 0.3 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 39/78 39
Typická vlastnost hierarchie class Příklad modelu pro hypotéky skládá se z 1 Nemov itost - označení: string - hodnota: penize +vlastní +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* Nemovitost se zde chápe jako jednotka vlatnictví. Pokud nějakou nemovitost vlatsní více osob, rozdělí se na samostatné části dle podílu vlastníků. + žádost(peníze, Nemovitost) : boolean +pro 1 Nemovitost se nemůže skládat sama ze sebe. +zajišťuje 1..* Hypotéka - od: datum - do: datum - celková_č ástka: peníze - měsíční_splátka: peníze +má_půjčenu context Nemovitost inv : not (self.skládá_se_z iselement(self)) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 40/78
Příklad použití OCLV. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +ow ner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Nikdo nevlastní víc než 3 černá vozidla: context Person inv: self.fleet -> select(v v.colour = Colour::black)-> size <= 3 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 41/78
Příklad použití OCLVI. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Co znamená podmínka? context Person inv: self.fleet -> iterate(v ; acc:integer=0 if (v.colour = Colour::black) then acc+1 else acc endif) <= 3 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 42/78
Příklad použití OCLVII. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Co znamená podmínka? context Person inv: self.fleet -> age < 18 implies forall(v not v.ocliskindof(car)) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 43/78
Příklad použití OCLVIII. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Existuje červené auto: context Car inv: Car.allInstances -> exists(c c.colour = Colour::red) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 44/78
Příklad použití OCLIX. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Metoda setage třídy Person pro nezáporný argument newage nastaví atribut age: context Person::setAge(newAge:Integer):Integer pre: newage >= 0 post: self.age = newage richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 45/78
Příklad použití OCLX. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Vyvolání metody birthday třídy Person zvýší věk osoby o 1: context Person::birthday() post: self.age = self.age@pre + 1 richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 46/78
Příklad použití OCLXI. class Auta Person - name: String - birthdate: Date - /age: int + getname() : String {query} + birthday() : Date + setage(int) : int +owner 1 ownership Vehicle +fleet - colour: Colour «enumeration» Colour black white red Date - day: int - month: int - year: int Car Bike Výsledek volání metodygetnametřídy Person je hodnota atributu name: context Person::getName():String post: result = self.name nebo, protože getname je {query}: context Person inv: self.getname = self.name richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 47/78
Úrovně modelů richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 48/78
Příklad využití OCL (metamodeluml) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 49/78
Příklad podmínky v OCL (metamodel) class Model elementu «metaclass» Element - mustbeowned: boolean +owner 0..1 Element, který musí mít vlastníka, musí mít vlastníka. +ownedelement context Element inv: self.mustbeowned() implies owner->notempty() richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 50/78
Příklad: definice odvozené vlastnosti Elementy, které vlastní daný element (je to odvozené sjednocení). /ownedelement: Element[*] richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 51/78
Příklad: definice odvozené vlastnosti Element, který vlastní tento element (owner) je to odvozené sjednocení (union). /owner: Element [0..1] richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 52/78
Příklad: popis operace v OCL Operace allownedelements() vrací všechny elementy, které přímo či nepřímo vlastní daný element context Element::allOwnedElements(): Set(Element) post: result = ownedelement -> union( ownedelement->collect(e e.allownedelements() ) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 53/78
Příklad: podmínky v OCL Element nemůže přímo, nebo nepřímo vlastnit sám sebe context Element inv: not self.allownedelements() -> includes(self) richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 54/78
The End richta@fel.cvut.cz (ČVUT) OCL a integritní omezení BI-SI1, 2011, Přednáška 9, 55/78