Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Object Constraint Language (OCL) – wersja 2.0 Standardowy język definicji ograniczeń dla modeli UML.

Podobne prezentacje


Prezentacja na temat: "Object Constraint Language (OCL) – wersja 2.0 Standardowy język definicji ograniczeń dla modeli UML."— Zapis prezentacji:

1 Object Constraint Language (OCL) – wersja 2.0 Standardowy język definicji ograniczeń dla modeli UML

2 Wprowadzenie OCL jest formalnym językiem specyfikacji wyrażeń występujących w modelach UML Wyrażenia OCL nie mogą mieć efektów ubocznych – nie mogą zmieniać stanu systemu OCL może natomiast specyfikować zmianę stanu OCL nie jest językiem programowania Nie da się w nim wyrazić zagadnień związanych z implementacją

3 Użycie wyrażeń OCL Specyfikacja zapytań Specyfikacja niezmienników klas i typów danych w modelu klas Specyfikacja niezmienników typu dla stereotypów Specyfikacja warunków wstępnych (preconditions) i warunków końcowych (postconditions) dla operacji i metod Specyfikacja warunków dozoru (guards) Specyfikacja celu komunikatów i akcji Specyfikacja ograniczeń dla operacji Specyfikacja reguł wyprowadzenia atrybutów pochodnych

4 Przykładowy diagram klas

5 Związki OCL z metamodelem UML – określenie kontekstu Każde wyrażenie OCL jest pisane w kontekście pewnej instancji konkretnego typu Wewnątrz wyrażenia instancja stanowiąca kontekst określana jest słowem zarezerwowanym self Kontekst wewnątrz wyrażenia można określić przy pomocy deklaracji kontekstu context Company

6 Związki z metamodelem UML – niezmienniki Niezmiennik to rodzaj ograniczenia, który musi być spełniony przez wszystkie instancje danego klasyfikatora w każdej chwili. context Company inv: self.numberOfEmployees > 50 self zazwyczaj można opuścić: context Company inv: numberOfEmployees > 50

7 Związki z metamodelem UML – niezmienniki (c.d.) Można zdefiniować symbol zastępujący self: context c: Company inv: c.numberOfEmployees > 50 Ograniczenie może mieć nazwę: context c: Company inv enoughEmployees: c.numberOfEmployees > 50

8 Związki z metamodelem UML – warunki wstępne i końcowe Kontekstem jest operacja lub inna cecha czynnościowa self jest instancją typu, do którego należy dana cecha czynnościowa Słowo zarezerwowane result określa wynik operacji context Type::operation(par1: T1,...): ReturnType pre:... post:...

9 Związki z metamodelem UML – warunki wstępne i końcowe (c.d.) Przykład warunku końcowego: context Person::income(d: Date): Integer post: result = 5000 Warunki wstępne i końcowe mogą mieć nazwy: context ClassA::op(par: T): ReturnType pre parameterOk: par > 63 post resultOk: result = par + 23

10 Związki z metamodelem UML – określenie kontekstu pakietu package A::B context C inv:... context C::op1() pre:... endpackage

11 Związki z metamodelem UML – ograniczenia na zwracaną wartość Ograniczenia body condition dla operacji będących zapytaniami context ClassA::op(): T body:... Przykład: context Person::getCurrentSpouse(): Person pre: self.isMarried = true body: self.marriages->select(ended = false).spouse

12 Związki z metamodelem UML – wartości początkowe i pochodne Wyrażenia OCL mogą opisywać wartości początkowe lub pochodne (wyprowadzone) atrybutów i końców powiązań context Person::income: Integer init: parents.income->sum() * kieszonkowe derive: if underAge then parents.income->sum() * 0.01 else job.salary endif

13 Typy podstawowe OCL Integer Operacje (przykładowe): +, -, *, /, abs() Real +, -, *, floor() Boolean and, or, xor, not, implies, if-then-else String concat(), size(), substring()

14 Typy z modeli UML Wszystkie klasyfikatory zdefiniowane w danym modelu UML są typami dostępnymi w wyrażeniach OCL dołączonych do tego modelu

15 Typy wyliczeniowe context Person inv: wife.gender = Gender::female

16 Definiowanie zmiennych o zasięgu pojedynczego wyrażenia context Person inv: let income: Integer = job.salary->sum() in if isUnemployed then income < 100 else income >= 100 endif

17 Definiowanie dodatkowych atrybutów/operacji Przy pomocy ograniczeń oznaczonych stereotypem > można w wyrażeniach OCL definiować dodatkowe atrybuty i operacje klasyfikatorów Pozwala to współdzielić zmienne i operacje pomiędzy kilkoma ograniczeniami Dodatkowe cechy stają się zwykłymi atrybutami i operacjami klasyfikatora o stereotypie >

18 Definiowanie atrybutów/operacji – przykład context Person def: income: Integer = job.salary->sum() def: nickname: String = Super Dyzio def: hasTitle(t: String): Boolean = job->exists(title = t)

19 Zgodność typów Każdy typ jest zgodny z każdym swoim nadtypem (uogólnieniem) Relacja zgodności jest przechodnia (nie jest symetryczna) Typ kolekcji elementów typu T1 jest zgodny z typem kolekcji elementów typu T2 o ile T1 jest zgodny z T2 Collection(T1) jest zgodny z Collection(T2) o ile T1 jest zgodny z T2 Ta sama reguła obowiązuje dla par Set(T1)/Set(T2), OrderedSet(T1)/OrderedSet(T2), Bag(T1)/Bag(T2) i Sequence(T1)/Sequence(T2)

20 Komentarze w OCL Komentarze wierszowe – od dwuznaku -- do końca linii -- komentarz wierszowy Komentarze blokowe – ograniczone dwuznakami /* i */ /* komentarz blokowy */

21 Wartości nieokreślone Są wynikiem niektórych operacji (np. branie pierwszego elementu pustej kolekcji) Na ogół wyrażenie o składowych nieokreślonych ma wartość nieokreśloną Wyjątek stanowią wyrażenia logiczne, w których wartość nieokreślona spełnia reguły logiki trójwartościowej Można jawnie testować, czy dany obiekt ma wartość nieokreśloną przy pomocy operacji oclIsUndefined() typu OclAny

22 Atrybuty obiektów context Person inv: self.age > 0 Wynikiem wyrażenia jest wartość typu atrybutu W przypadku atrybutów o krotności większej niż 1 wynikiem jest kolekcja

23 Operacje obiektów Zwykłe wywołanie operacji – wynikiem jest wartość typu zwracanego przez operację aPerson.income(aDate) Jeśli operacja ma parametry inout lub out wynikiem jest krotka (tuple) złożona ze wszystkich parametrów out, inout i zwracanej wartości

24 Przykład operacji Jeśli operacja ma sygnaturę Person::income(d: Date, out bonus: Integer): Integer to wynikiem jej wywołania jest krotka typu Tuple(bonus: Integer, result: Integer) do której składowych można odwołać się następująco: p.income(d).bonus = 100 and p.income(d).result = 3000

25 Końce powiązań i nawigacja context Company inv: self.manager.isUnemployed = false inv: self.employee->size() <= 50 Jeśli krotnością końca jest co najwyżej 1 wartością wyrażenia jest obiekt odpowiedniego typu self.manager to obiekt klasy Person Jeśli koniec ma górne ograniczenie krotności większe niż 1 wartością jest kolekcja standardowo Set(T), dla właściwości uporządkowanych OrderedSet(T) self.employee to kolekcja Set(Person)

26 Brakujące nazwy końców powiązań Wyprowadzane są z nazw typów na końcach przez zamianę pierwszej litery na małą

27 Końce o krotności nie większej niż 1 Mogą być traktowane jako pojedyncze obiekty albo zbiory złożone z pojedynczych obiektów (lub puste) context Person inv: self.wife->notEmpty() implies self.wife.gender = Gender::female

28 Klasy powiązań Do specyfikacji nawigacji do klasy powiązania OCL stosuje regułę nazewniczą analogiczną do reguły brakującej nazwy końca context Person inv: self.job->size() <= self.age

29 Klasy powiązań zwrotnych Nawigacja w stronę końca bosses self.employeeRanking[bosses]->sum() > 0 Nawigacja w stronę końca employees self.employeeRanking[employees]->sum() > 0

30 Powiązania kwalifikowane W przypadku użycia wartości kwalifikatora otrzymujemy pojedynczy obiekt context Bank inv: self.customer[11].gender = Gender::male Opuszczając kwalifikator otrzymujemy kolekcję context Bank inv: self.customer->size() >= 30000

31 Predefiniowane operacje wszystkich obiektów Następujące operacje są zdefiniowane we wspólnym przodku wszystkich typów OCL, tzn. OclAny, a zatem są dostępne dla wszystkich obiektów: oclIsTypeOf(t: OclType): Boolean oclIsKindOf(t: OclType): Boolean oclInState(s: OclState): Boolean oclIsNew(): Boolean oclIsUndefined(): Boolean oclIsInvalid(): Boolean oclAsType(t: OclType): T allInstances(): Set(T)

32 Dostęp do przedefiniowanych atrybutów i operacji Jeśli B jest podklasą A i przedefiniowuje właściwość A::p1 i jeśli self jest klasy B to self.p1 oznacza (zawsze) B::p1, natomiast self.oclAsType(A).p1 oznacza A::p1

33 Przykład cechy klasowej context Singleton inv: Singleton.allInstances()->size() <= 1

34 Przykład określenia stanu obiektu c.oclInState(On) c.oclInState(Off) c.oclInState(Off::NoPower)

35 Wartości poprzednie w warunkach końcowych W warunku końcowym wartość właściwości jest rozumiana jako jej wartość w momencie zakończenia operacji stanowiącej kontekst Jednak często jest potrzebne odniesienie do wartości właściwości w momencie rozpoczynania operacji – służy do tego operator context Company::hireEmployee(p: Person) post: numberOfEmployees = + 1 and employee = and stockprice() = + 10

36 Wartości poprzednie (c.d.) Jeśli wartością poprzednią właściwości jest obiekt, to jego dla jego właściwości uwzględniane są wartości aktualne chyba że jawnie wyspecyfikujemy odniesienie do wartości poprzednich

37 Krotki Krotka jest zestawem nazwanych części o zróżnicowanych typach. Poniższe definicje literałów krotkowych są równoważne. Tuple {name: String = Kowalski, age: Integer = 20} Tuple {name = Kowalski, age = 20} Tuple {age = 20, name = Kowalski} Odniesienie do składowej części krotki: Tuple {age = 20, name = Jan}.age = 50

38 Kolekcje OCL OCL zawiera 5 typów kolekcji: Abstrakcyjny typ Collection(T) Specjalizujące go typy konkretne Set(T) – zbiór elementów typu T OrderedSet(T) – zbiór uporządkowany Bag(T) – wielozbiór (zbiór z powtórzeniami) Sequence(T) – ciąg (wielozbiór uporządkowany)

39 Kolekcje OCL a nawigacja powiązań Kolekcje są wynikami nawigacji powiązań Set(T) dla powiązań prostych (bez dodatkowych atrybutów) Bag(T) dla powiązań złożonych oraz prostych z powtórzenami OrderedSet(T) dla powiązań prostych uporządkowanych Sequence(T) dla powiązań prostych uporządkowanych z powtórzeniami

40 Literały kolekcji Set { zielony, niebieski, czerwony } OrderedSet { Ala, Ela, Ola } Bag { 1, 1, 3, 5, 1, 10, 10 } Dla literałów ciągów istnieje notacja skrótowa. Poniższe definicje są równoważne: Sequence { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } Sequence { } Sequence { 1..(3+7) }

41 Operacje na kolekcjach Standardowa biblioteka OCL zawiera dużą liczbę operacji typu Collection(T) i jego podtypów Zapewnia to możliwość manipulowania standardowymi kolekcjami Operacje standardowe nigdy nie zmieniają stanu kolekcji (są zapytaniami)

42 Operacja select Pozwala wyspecyfikować podzbiór wyjściowej kolekcji przez podanie warunku przynależności Składnia collection->select(warunek) collection->select(v | warunek-z-v) collection->select(v: Typ | warunek-z-v)

43 Operacja select – przykłady context Company inv: employee->select(age > 50)->notEmpty() context Company inv: employee->select(p | p.age > 50)->notEmpty() context Company inv: employee->select(p: Person | p.age > 50)->notEmpty()

44 Operacja reject Operacja o składni analogicznej do select, ale określająca warunek odrzucenia context Company inv: employee->reject(isMarried)->isEmpty() context Company inv: employee->reject(p | p.isMarried)->isEmpty() context Company inv: employee->reject(p: Person | p.isMarried)->isEmpty()

45 Operacja collect Konstruuje kolekcję wywiedzioną z danej kolekcji, ale zawierającą inne obiekty Set(T) przekształca w Bag(T) OrderedSet(T) przekształca w Sequence(T) Przykład (definicje równoważne) employee->collect(birthDate) employee->collect(person | person.birthDate) employee->collect(p: Person | p.birthDate)

46 Operacja collect – notacja skrótowa Zamiast employee->collect(birthDate) self.employee->collect(income( )) można pisać employee.birthDate self.employee.income( )

47 Kwantyfikator ogólny context Company inv: employee->forAll(age <= 65) context Company inv: employee->forAll(p | p.age <= 65) context Company inv: employee->forAll(p: Person | p.age <= 65) context Company inv: employee->forAll(e1, e2 | e1 <> e2 implies e1.lastName <> e2.lastName)

48 Kwantyfikator szczegółowy context Company inv: employee->exists(firstName = Elvis) context Company inv: employee->exists(p | p.firstName = Elvis) context Company inv: employee->exists(p: Person | p.firstName = Elvis)

49 Operacja iterate Najogólniejsza z operacji iteratorowych Pozwala stworzyć nową kolekcję na podstawie danej przy pomocy jawnie określonego wyrażenia collection->iterate(e: Type; acc: Type2 = | wyrażenie-z-e-i-acc)

50 Operacja iterate - przykład Następująca operacja collect collection->collect(x: T | x.property) może być zdefiniowana przy pomocy iterate w następujący sposób collection->iterate(x: T; acc: Bag(T2) = Bag {} | acc->including(x.property))

51 Dodatkowe operacje typu Collection(T) includes(object: T): Boolean excludes(object: T): Boolean count(object: T): Boolean includesAll(c: Collection(T)): Boolean excludesAll(c: Collection(T)): Boolean sum(): T product(c: Collection(T2)): Set(Tuple(first: T, second: T2))

52 Dodatkowe operacje wspólne dla Bag(T), Set(T) i Sequence(T) operator = (również dla OrderedSet(T)) including(object: T): odpowiednia_kolekcja excluding(object: T): odpowiednia_kolekcja flatten(): odpowiednia_kolekcja asSet(): Set(T) asBag(): Bag(T) asOrderedSet(): OrderedSet(T) asSequence(): Sequence(T)

53 Dodatkowe operacje wspólne dla Set(T) i Bag(T) union(s: Set(T)): odpowiednia_kolekcja union(b: Bag(T)): Bag(T) intersection(s: Set(T)): Set(T) intersection(b: Bag(T)): odp_kolekcja

54 Dodatkowe operacje kolekcji uporządkowanych append(object: T): odpowiednia_kolekcja prepend(object: T): odpowiednia_kolekcja insertAt(index: Integer, object: T): odpowiednia_kolekcja at(index: Integer): T indexOf(object: T): Integer first(): T last(): T

55 Dodatkowe operacje Set(T) operator - (s: Set(T)): Set(T) symmetricDifference(s: Set(T)): Set(T) OrderedSet(T) subOrderedSet(lower: Integer, upper: Integer): OrderedSet(T) Sequence(T) subSequence(lower: Integer, upper: Integer): Sequence(T)

56 Dodatkowe operacje iteratorowe Collection(T) isUnique(iterator | body): Boolean any(iterator | body): T one(iterator | body): Boolean Set(T) sortedBy(iterator | body): OrderedSet(T) Bag(T) i Sequence(T) sortedBy(iterator | body): Sequence(T)

57 Komunikaty w OCL Komunikaty (instancje OclMessage) służą do specyfikacji zdarzenia komunikacyjnego – wywołania operacji lub wysłania sygnału Operator ^ określa czy komunikat został wysłany context Subject::hasChanged() post: observer^update(3, 19) context Subject::hasChanged() post: observer^update(?, ?) context Subject::hasChanged() post: observer^update(?: Integer, ?: Integer)

58 Analiza instancji komunikatów Operator ^^ zwraca ciąg rzeczywiście wysłanych komunikatów observer^^update(3, 4) Formalne parametry komunikatu są dostępne jako atrybuty instancji OclMessage context Subject::hasChanged() post: let msgs: Sequence(OclMessage) = observer^^update(?, ?) in msgs->notEmpty() and msgs->exists(m | m.j > m.i)

59 Analiza instancji komunikatów (c.d.) Analiza komunikatów wysłanych do różnych obiektów context Subject::hasChanged() post: let msgs: Sequence(OclMessage) = observers->collect(o | o^^update(?, ?)) in msgs->forAll(m | m.i < m.j)

60 Przetwarzanie zwracanych wartości context Person::giveSalary(amount: Integer) post: let msg: OclMessage = company^^getMoney(amount) in msg.hasReturned() and msg.result() = true

61 Pozostałe operacje klasy OclMessage isOperationCalled(): Boolean isSignalSent(): Boolean

62 Inne typy specjalne OCL OclVoid Jedyna instancja nazywa się null (odpowiada specyfikacji wartości UML NullLiteral) OclInvalid Jedyna instancja nazywa się invalid OclElement OclType

63 Rozwiązywanie konfliktów nazw właściwości Może zachodzić w przypadku zmiennych niejawnych self niejawne iteratory Rozstrzygane na korzyść zmiennych z najbardziej wewnętrznego zasięgu

64 Przykład konfliktu nazw context Person inv: employer->forAll( employee->exists(lastName = name) ) znaczy to samo, co context Person inv: employer->forAll( employee->exists(p | p.lastName = name) )

65 Użycie wyrażeń OCL w modelach UML


Pobierz ppt "Object Constraint Language (OCL) – wersja 2.0 Standardowy język definicji ograniczeń dla modeli UML."

Podobne prezentacje


Reklamy Google