OCL (Object Constraint Language)

Jazyk Object Constraint Language (OCL) poskytuje rámec pro specifikaci omezení kladených na model formálním způsobem. Je speciálním případem textových anotací, které mají v textové formě specifikovat to co nelze vizualizuovat pomocí UML.

Výrazové prostředky jazyku OCL jsou deklarativní bez vedlejších efektů, což znamená, že nedojde k žádným změnám stavu systému z důvodů vyhodnocení výrazů jazyka OCL.  Omezení, která chceme tímto jazykem specifikovat se týkají jak statické struktury tak dynamického chování systému.

Invarianty - jsou omezení kladená na statickou strukturu. Invariantou rozumíme podmínku, která musí být splněna instancemi daného typu v libovolném čase.

OCL je specifikační jazyk - je určen pro vyjádření invariantů. Zápisy v OCL je třeba chápat jako specifikaci pro programy, které budou odpovídající integritní omezení zajišťovat.

Zápis v jazyce OCL má vždy jednotný tvar:

context <jméno> [inv|pre|post]: <výraz>

Příklad: context Osoba inv: self.příjem > 10000

Vyjadřuje, že pro každou instanci třídy Osoba, musí mít její atribut příjem hodnotu větší než 10000.
V daném kontextu nelze evidovat osoby s nižším příjmem.


Stereotypy inv, pre a post znamenají:

  • inv = <<invariant>> (obecně platné tvrzení - omezení)
  • pre = <<precondition>> (vstupní podmínky operace - předpoklad)
  • post = <<postcondition>> (podmínka, která platí po příslušné akci).


OCL je silně typovaný jazyk, tj. každý výraz v jazyce OCL má definován typ. To umožňuje silnou statickou typovou kontrolu zapsaných omezení při jejich interpretaci. OCL má předdefinovánu sadu typů – jsou to jednak primitivní typy: Integer, Boolean, String, Real, UnlimitedInteger, ze kterých lze vytvářet složené typy jako rozmanité kolekce: množina (Set), multi-množina (Bag), obecná kolekce (Collection), posloupnost (Sequence), atd. 

Příklad: Diagram tříd modelující zaměstnance, oddělení a projekty. Z modelu vyplývá, že zaměstnanci pracují pro oddělení firmy na projektech, která jsou prostřednictvím oddělení řízena. 

Nyní definujeme integritní omezení v OCL:

  • Podmínka, že rozpočet oddělení nesmí být záporný:

context Oddělení inv: 

self.rozpočet >= 0

  • Korektní zvýšeníPlatu vyžaduje splnění omezující podmínky, kdy v případě kladné částky bude mít zaměstanec o tuto částku navýšen svůj plat. Aplikací výrazu @pre ve výstupní podmínce rozumíme použití předchozí hodnoty daného atributu.

context Zaměstnanec::zvýšeníPlatu(částka : Real) : Real 

pre: částka > 0   

post: self.plat = self.plat@pre + částka   and result = self.plat

  • V řadě případů je možné použít nějaký výraz na více místech omezení. K dispozici je výraz let, který umožňuje definovat atribut či operaci v rámci daného omezení. Pokusme se pro zaměstnance naší firmy definovat omezení, že není možné, aby pracoval na více než třech projektech, ale je také nepřípustné, aby nepracoval na žádném. Příkaz size() nám vrací  velikost množiny - počet projektů. 

context Zaměstnanec inv:   

let počet : Integer = self.projekt->size() in   

if počet <= 3 and počet > 0 then   true   

else   false   

endif   

  • Pokud budeme chtít z množiny projektů, na kterých zaměstnanec pracuje, vytvořit novou kolekci (collection) obsahující pouze rozpočty těchto projektů, zapíšeme to takto: 

self.projekt->collect(rozpočet) 

  • Nad kolekcemi můžeme provádět i další operace jako je např. součet sum(), který v případě platnosti operace sčítaní sečte všechny prvky dané kolekce. V příkladu součtu rozpočtů projektů, na kterých zaměstnanec pracuje, pak bude výsledný výraz následující: 

self.projekt.rozpočet->sum() 

 

Podrobnější vysvětlení s více příklady najdete zde

  Zdrojem jsou skripta - Metody specifikace softwarových systémů (Prof. Ing. Ivo Vondrák, CSc.)

Kam dál?