Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Standardy w zakresie systemów rozproszonych i baz danych

Podobne prezentacje


Prezentacja na temat: "Standardy w zakresie systemów rozproszonych i baz danych"— Zapis prezentacji:

1 Standardy w zakresie systemów rozproszonych i baz danych
Wykład 11: c.d. Wprowadzenie do OCL Piotr Habela Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa

2 Specyfikacja OCL (1) Deklarowanie zmiennych Operator if Porównania
OclExpressionCS ::=  'let' VariableDeclarationListCS 'in' OclExpressionCS Przykład: let zmienna: TypZmiennej = wyrażenie1 in wyrażenie2 Operator if OclExpressionCS ::=  'if' OclExpressionCS 'then' OclExpressionCS 'else' OclExpressionCS 'endif' W OCL dla wyrażenia 'if' część 'else' jest obowiązkowa Przykład: if wiek < 35 then ‘młody' else ‘stary' Porównania OclExpressionCS ::= OclExpressionCS Porównanie OclExpressionCS Porównanie ::= '='  | '<>' | '<'  | '>'  | '<=' |'>=‘ Operatory arytmetyczne OclExpressionCS ::= OclExpressionCS OperatorArytmet OclExpressionCS OperatorArytmet ::= ‘+' | ‘-'  | ‘*' | ‘/'

3 Specyfikacja OCL (2) Wołanie operacji infiksowych
OclExpressionCS ::= OclExpressionCS simpleNameCS OclExpressionCS simpleNameCS pochodzi z biblioteki OCL Przykład: booleanExpression1 implies booleanExpression2 Wołanie operacji prefiksowych OclExpressionCS ::= '-' OclExpressionCS | simpleNameCS OclExpressionCS Przykład: not booleanExpression Iteratory na pojedynczych zmiennych OclExpressionCS ::= OclExpressionCS '->' simpleNameCS '(' VariableDeclarationCS '|' OclExpressionCS ')' Przykłady: employees -> select (e | e.age < 50) employees -> select (p: Person | p.age < 50) Iteratory na dwóch zmiennych OclExpressionCS ::= OclExpressionCS '->' simpleNameCS '(' VariableDeclarationCS ',' VariableDeclarationCS '|' OclExpressionCS ')' Pierwsze OclExpressionCS musi być pojedynczą nazwą Przykład: employees -> forAll (e1, e2 | e1 <> e2 implies e1.empno <> e2.empno)

4 Specyfikacja OCL (3) Wołanie operacji na kolekcjach
OclExpressionCS ::= OclExpressionCS '->' simpleNameCS '(' ')' Przykład: employees -> count() OclExpressionCS ::= OclExpressionCS '->' simpleNameCS '(' OclExpressionCS argumentsCS_trail ')' Przykład: employees -> sortedBy(surname) argumentsCS_trail – być może pusta lista dalszych argumentów Zwyczajne wołanie operacji OclExpressionCS ::= OclExpressionCS '.' simpleNameCS '(' argumentsCS ')' Przykład: employees -> select (age < 35).raise(100) Wiązanie atrybutu lub zmiennej OclExpressionCS ::= OclExpressionCS '.' simpleNameCS | simpleNameCS Wołanie operacji OclExpressionCS ::= simpleNameCS '(' ')' | simpleNameCS '(' argumentsCS ')'

5 OCL – ścieżki dostępu, literały
pathNameCS ::= simpleNameCS '::' simpleNameCS | simpleNameCS '::' pathNameCS Ta reguła reprezentuje ścieżkę nazw, która jest używana do dostępu do nazw (np. typów) w innych pakietach. Przykład: packageA::subpackageA1::typeX Literały: LiteralExpCS ::= CollectionLiteralExpCS| TupleLiteralExpCS| PrimitiveLiteralExpCS CollectionLiteralExpCS ::= CollectionTypeIdentifierCS '{‘ CollectionLiteralPartsCS '}' Przykłady: OrderedSet {'first', 'second', 'third'} Bag {10, 20, 10, 50, 50} Identyfikatory kolekcji: 'Set', 'Bag', 'Sequence', 'OrderedSet' Literały kolekcji określane przez zakres: CollectionRangeCS ::= OclExpressionCS '..' OclExpressionCS Przykład: Sequence { 1..12, }

6 Prymitywne literały i krotki
PrimitiveLiteralExpCS ::= IntegerLiteralExpCS | RealLiteralExpCS | StringLiteralExpCS | BooleanLiteralExpCS Włączają literały: Real, Boolean, Integer, String Krotki (struktury) TupleLiteralExpCS ::= 'Tuple' '{' VariableDeclarationListCS '}‘ Reguła reprezentuje literały reprezentujące krotki Przykład: Tuple {name: String = 'John', surname: String = 'Brown', age: Integer = 47}

7 Deklaracje zmiennych, typy i argumenty
VariableDeclarationCS ::= VariableDeclarationCS_strict | simpleNameCS Typ i wyrażenie inicjujące są opcjonalne. Przykłady: p: Person i: Integer = 7 VariableDeclarationCS_strict ::= simpleNameCS ':' typeCS | simpleNameCS ':' typeCS '=' OclExpressionCS | simpleNameCS '=' OclExpressionCS typeCS ::= simpleNameCS | pathNameCS | collectionTypeCS | tupleTypeCS collectionTypeCS ::= CollectionTypeIdentifierCS '(' typeCS ')' Przykłady: Bag(Integer) Sequence(String) OrderedSet(String) tupleTypeCS ::= 'TupleType' '(' VariableDeclarationListCS ')' Przykład: TupleType(name: String, surname: String, age: Integer) argumentsCS ::= OclExpressionCS argumentsCS_trail ? argumentsCS_trail ::= ',' OclExpressionCS argumentsCS_trail ?

8 Operacje na typie Boolean
Operator Przykład Typ rezultatu Opis or a or b Boolean Alternatywa and a and b Koniunkcja xor a xor b Alternatywa wyłączna not not a Negacja = a = b Równość <> a <> b Nierówność implies a implies b Implikacja

9 Operacje na typach Integer i Real
Operator Przykład Typ rezultatu Opis = <> a = b Boolean Równość , nierówność < <= a < b Mniejszy, mniejszy lub równy > >= a > b Większy, większy lub równy a + b Integer lub Real Dodawanie, odejmowanie * / a * b Mnożenie, dzielenie mod a.mod(b) Integer Modullo (reszta od dzielenia) div a.div(b) Dzielenie liczb całkowitych abs a.abs() Wartość absolutna max a.max(b) Wartość maksymalna z a i b min a.min(b) Wartość minimalna z a i b round a.round() Wartość zaokrąglona floor a.floor() Wartość zaokrąglona w dół

10 Operacje na typie String
Operator Przykład Typ rezultatu Opis = <> a = b Boolean Równość , nierówność concat + a.concat(b) a + b String Konkatenacja Konkatenacja dodana w VIDE toLower a.toLower() Zmiana na małe litery toUpper a.toUpper() Zmiana na duże litery substring a.substring(i, j) Wybranie podstringu od i-tego do j-tego znaku Postfiksowa konwencja a la Smalltalk nie jest fortunnym pomysłem twórców OCL Klasyczna konwencja, np. toUpper(a), wydaje się dużo lepsza.

11 Standardowe operatory na kolekcjach
Przykład Typ rezultatu Opis count x->count(y) Integer Liczba wystąpień obiektu y w kolekcji x excludes x->excludes(y) Boolean True jeżeli y nie jest elementem x excludesAll x->excludesAll(y) True jeżeli nie ma elementu kolekcji y, który jest jednocześnie elementem x includes x->includes(y) True jeżeli y jest elementem x includesAll x->includesAll(y) True jeżeli wszystkie elementy kolekcji y są w x isEmpty x->isEmpty() True jeżeli kolekcja x jest pusta notEmpty x->notEmpty() True jeżeli kolekcja x jest niepusta

12 Funkcje agregowane Operator Przykład Typ rezultatu Opis size x->size() Integer Liczba elementów w kolekcji x sum x->sum() Integer lub Real Suma arytmetyczna elementów kolekcji x avg x->avg() Real Średnia arytmetyczna elementów kolekcji x min x->min() Integer, Real lub String Najmniejsza wartość w kolekcji x max x->max() Największa wartość w kolekcji x Operatory sum, avg, min i max zostały wprowadzone w VIDE, są rozszerzeniem standardu.

13 Dalsze operatory na kolekcjach (1)
Przykład Typ rezultatu Opis = x = y Boolean Identyczność kolekcji x i y <> x <> y Przecięcie kolekcji x i y jest puste - x - y set Różnica zbiorów: wynik zawiera te elementy x, których nie ma w y append x->append(o) OrderedSet lub Sequence Dodaj element o na koniec sekwencji x asBag x->asBag() Bag Konwersja do Bag asOrderedSet x->asOrderedSet() OrderedSet Konwersja do OrderedSet asSequence x->asSequence() Sequence Konwersja do Sequence asSet x->asSet() Set Konwersja do Set

14 Dalsze operatory na kolekcjach(2)
Przykład Typ rezultatu Opis at x->at(i) object Zwraca element kolekcji x znajdujący się na pozycji i excluding x->excluding(o) collection Zwraca kolekcję x pomniejszoną o element o first x->first() Pierwszy element kolekcji x flatten x->flatten() Spłaszcza zagnieżdżoną kolekcję x o jeden poziom including x->including(o) Zwraca kolekcję x zwiększoną o element o indexOf x->indexOf(o) Integer Zwraca numer pozycji elementu o w kolekcji x insertAt x->insertAt(i, o) OrderedSet lub Sequence Zwraca OrderedSet lub Sequence, w których wstawiony został element o na pozycję i intersection x->intersection(y) Set lub Bag Przecięcie kolekcji x i y last x->last() Ostatni element w kolekcji x

15 Dalsze operatory na kolekcjach (3)
Przykład Typ rezultatu Opis prepend x->prepend(o) OrderedSet lub Sequence Dodaje element o jako pierwszy przed kolekcją x subOrderedSet x->subOrderedSet(i, j) OrderedSet Wybiera elementy sekwencji od i-tego do j-tego; rezultat typu OrderedSet subSequence x->subSequence(i, j) Sequence Wybiera elementy sekwencji od i-tego do j-tego; rezultat typu Sequence symmetricDifference x -> symmetricDifference(y) Set Zawiera elementy x, których nie ma w y, i vice versa union x->union(y) collection Suma dwóch kolekcji lub konkatenacja sekwencji Wątpliwości budzi redundancja operatorów, np. symmetricDifference łatwo wyrazić przez sumę i różnicę kolekcji: x sD y = (x – y)  (y – x) = (x  y) – (x ∩ y) Niekiedy ma znaczenie, czy operacja jest dokonywana na zapamiętanej kolekcji, czy też na kolekcji obliczonej poprzez zapytanie. Np. wstawienie nowego elementu do zapamiętanego zbioru (including) jest nieco inną operacją.

16 Operatory pętli i zmienne iteracyjne (1)
Przykład Typ rezultatu Opis any x->any(e) object Wybiera dowolny element z kolekcji x dla którego wyrażenie e jest prawdziwe collect x->collect(e) collection Projekcja: zwraca wartości wyrażenia e dla każdego elementu kolekcji x collectNested x-> collectNested(e) Tak samo jak dla collect, ale dotyczy to kolekcji kolekcji iterate x->iterate( i: Type1; a: Type2=e1 | e2) Type2 Zmiennej a jest początkowo przypisana wartość wyliczona przez e1. Zmienna iteracyjna i iteruje po kolekcji x i w każdym obrocie jest wyliczane e2 dla tego i oraz a. Wartość ta jest podstawiana pod a. Funkcja agregowana sum: x->iterate(i: Integer; a: Integer=0 | a+i) Funkcja agregowana max: x->iterate(i: Integer; a: Integer= -9999| i.max(a))

17 Operatory pętli i zmienne iteracyjne (2)
Przykład Typ rezultatu Opis exists x->exists(e) Boolean Kwantyfikator egzystencjalny: zwraca true jeżeli e jest true dla przynajmniej jednego elementu x forAll x->forAll(e) Kwantyfikator uniwersalny: zwraca false jeżeli e jest false dla przynajmniej jednego elementu x isUnique x->isUnique(e) Zwraca true jeżeli wyrażenie e zwraca różną wartość dla każdego elementu x one x->one(e) Zwraca true jeżeli e jest true dla dokładnie jednego elementu x reject x->reject(e) collection Zwraca te elementy x, dla których e jest false select x->select(e) Zwraca te elementy x, dla których e jest true sortedBy x->sortedBy(e) OrderedSet lub Sequence Zwraca elementy kolekcji x posortowane zgodnie z wyrażeniem e

18 Przykłady wykorzystania OCL w VIDE
Emp name : String address : String salary: Integer boss[0..1] Dept name : String location: String[1..*] worksIn employs[0..*] Utwórz nowego pracownika newEmp := Emp create {name = ‘John’; address = ‘44th Street’; salary = 3000} Podaj nazwiska pracowników, których szefem jest Bert: Emp->select(worksIn.boss.name=’Bert’).name Dla każdego pracownika, którego szefem jest Smith i zarabiającego mniej niż 2000 podwyższ zarobek o 100: (Dept ->select (boss.name = ‘Smith’).employs -> select (salary < 2000) foreach salary += 100; Czy to prawda, że w każdym dziale istnieje pracownik zarabiający więcej od swego szefa? (Dept -> forAll(d | d.employs -> exists(e | e.salary > d.boss.salary))

19 Dalsze przykłady (1) Dept->allInstances()->select(name=’toys’).employs->size() Dept->allInstances()->select(name=’toys’).employs.salary->sum() Dept->allInstances()->select(name=’toys’).employs.salary->avg() Dept->allInstances()->select(name=’toys’).employs.salary->min() Dept->allInstances()->select(name=’toys’).employs.salary->max() Niech Person będzie nadklasą dla Emp, zaś getIncome metodą zdefiniowaną dla Emp. Wówczas można wykorzystać dziedziczenie i polimorfizm: Person->allInstances()->collect(getIncome())->sum() Można także uzyskać efekt operatora zależnego złączenia (podaj identyfikator działu pod dept i sumaryczny zarobek pod totalSal): Dept->allInstances()->collect(d | Tuple{ dept = d, totalSal = d.employs.getSalary()->avg() } ) Tuple jest konstruktorem struktury allInstances: jeżeli przed -> jest nazwa klasy, to operator ten odzyskuje wszystkie obiekty tej klasy.

20 Dalsze przykłady i porównanie z SBQL
Dla każdej lokacji działu podaj zbiór nazw działów, które są tam ulokowane: Dept->allInstances()->collect(location)->asSet() ->collect(loc | Tuple{ L = loc, Dnames = (Dept->allInstances->select(location=loc)->collect(name))}) To samo zapytanie w SBQL (44 -> 22 jednostki leksykalne): unique(Dept.location) as L join ((Dept where L in location).name) groupas Dnames Dla każdej lokacji działu podaj zbiór nazw działów, które są tam ulokowane oraz średni zarobek szefów tych działów: Dept->allInstances()->collect(location)->asSet() ->collect(loc | Tuple{ L = loc, Dnames = Dept->allInstances->select(location=loc)->collect(name), bossAvg = Dept->allInstances->select(location=loc) ->collect(d | d.boss.salary)->avg()}) To samo zapytanie w SBQL: unique(Dept.location) as loc join ((Dept where loc in location) groupas d) . (loc as L, (d.name) groupas Dnames, (d.boss.Emp.salary) as bossAvg))

21 Jeszcze przykłady Podaj miasta goszczące wszystkie działy:
Dept->allInstances()-> select(d | (Dept->allInstances()->collect(location)->asSet()) ->forAll(loc | d.location -> exists(dloc | loc = dloc))) Załóżmy, że klasa Dept ma metodę budget pozwalającą na obliczenie rocznego budżetu działu. Dla każdego pracownika działu zlokalizowanych w Radomiu przygotuj komunikaty stringowe zawierające nazwisko oraz procent rocznego budżetu konsumowany przez tego pracownika. Emp->allInstances()->select(e | e.worksIn.location -> includes(‘Radom’))-> collect(‘Employee ‘ + name + ‘ consumes ‘ + (salary * 12 * 100 /(e.worksIn.Dept.budget())) + ‘ % of the " + worksIn.Dept.name + ‘ department budget.’) Zapis oryginalny w OCL: Emp->allInstances()->select(e | e.worksIn.location -> includes(‘Radom’))-> collect(‘Employee ‘.concat(name). concat(‘ consumes ‘). concat(salary * 12 * 100 /(e.worksIn.Dept.budget()). concat(‘ % of the ‘). concat(worksIn.Dept.name). concat(‘ department budget.’))

22 …i jeszcze przykład Dla każdego przedziału <n, n+999>, n = 0, 1000, 2000, 3000, ... przygotuj komunikat zawierający liczbę pracowników mających zarobek z tego przedziału i sam przedział. Komunikaty wyjściowe powinny mieć poprawną formę gramatyczną (w języku angielskim): przyrostki –s dla liczby mnogiej rzeczowników i dla czasowników w liczbie pojedynczej. Bag {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000} -> collect(i | Emp->allInstances()->select(salary >= i and salary < i+1000))->size()-> collect(c | if c = 1 then 1 + ‘ employee earns between ‘+ i +’ and ‘ + (i+999) else c + ‘ employees earn between ‘+ i +’ and ‘ + (i+999))

23 Przykłady użycia OCL w zdaniach imperatywnych
Daj minimalną płacę dla tych pracowników, którzy nie mają jeszcze określonej płacy. Emp->allInstances()->select(salary->size() = 0) foreach { e | e.raiseSalary(e.worksIn.getSalary()->min()); } Przesuń wszystkich pracowników z działu zabawek do działu badawczego Dept->allInstances()->select(name = ‘Toys’)->collect(employs) foreach { e |e unlink worksIn; e link worksIn to Dept->allInstances() ->select(name = ‘Research’);} Inny wariant: Emp->allInstances()->select(worksIn.name = ‘Toys’) foreach { e | e unlink worksIn; e link worksIn to Dept->allInstances()->select(name = ‘Research);} Daj 10% podwyżki wszystkim studentom, którzy są jednocześnie pracownikami działu znajdującego się w Warszawie: EmpStudent->allInstances()->select(worksIn.location->select(m| m = ‘Warsaw’) ) foreach { es | es.raiseSalary(es.getSalary * 0.1)); } Niektóre zapytania trudno uznać za łatwe, ale ważne jest, że da się je zadać.

24 Plusy i minusy OCL Plusy: Minusy
Język obsługuje pełny model obiektowy UML Jest ortogonalny (brak dużych zlepków takich jak select…from…where…group by…having...order by…) Jest dość popularny w środowisku UML Łatwa intuicyjna semantyka Minusy Fatalna składnia, przerosty składniowe, nieczytelne wyrażenia Jak dotąd, nie ma programistów w OCL Brak uniwersalności (np. żadnych możliwości rekurencyjnych) Niedospecyfikowanie (np.. brak semantyki dla zakresów nazw) Redundantny i trochę przypadkowy wybór funkcjonalności Nieprzystosowanie do roli języka zapytań (brak optymalizacji) Brak myślenia o zanurzeniu OCL w uniwersalny język programowania Brak perspektyw baz danych i innych abstrakcji programistycznych Brak efektów ubocznych Niejasny stosunek do wartości zerowych (podważa przykrycie SQL, gdzie wartości zerowe są ważną funkcjonalnością) Niespójność i przecinanie się funkcjonalności OCL z funkcjonalnością UML 2.1


Pobierz ppt "Standardy w zakresie systemów rozproszonych i baz danych"

Podobne prezentacje


Reklamy Google