Agregacja Agregacja jest rodzajem asocjacji; zadaniem agregacji jest modelowanie związku całość-część. agregacja jest asocjacją: dla obu jej końców są określane liczności, a także może mieć atrybuty, np. * 1..15 Grupa Student Termin od do agregacja jest wykorzystywana do modelowania związku całość-część * 1..15 Grupa Student całość część
Kompozycja jako mocna postać agregacji Pojęcie agregacji jest rozumiane na dwa sposoby: Jako związek część-całość pomiędzy obiektami świata rzeczywistego; np. silnik jest częścią samochodu. Jako pomocniczy środek do modelowania dowolnej innej sytuacji, kiedy trzeba wydzielić podobiekty w pewnych obiektach. np. informacja o ubezpieczeniach wewnątrz obiektów pracowników. W UML te dwie sytuacje zostały rozdzielone. Pierwszą formę nazwano kompozycją. Kompozycja oznacza, że cykl życiowy składowej zawiera się w cyklu życiowym całości, oraz że składowa nie może być współdzielona. K Ks K 1 Ks * * * agregacja kompozycja
Implementacja w Javie Roznica w implementacji pomiedzy agregacja a kompozycja polega na tym, ze w przypadku agregacji musimy odnosienia do obiektow pamietac w jakims zewmetrznym, stalym obiekcie i w samym obiekcie agregujacym. W ten sposob odsmiecacz nie skasuje naszych obiektow – czlonkow jesli przestanie istniec obiekt agregujacy. W przypadku kompozycji zabieg taki jest wrecz niewskazany. Jesli odniesienia do obiektow beda pamietane jedynie w obiekcie kompozycji, wowczas zysamy pewnosc, ze w przypadku usuniecia kompozycji usuniemy rowniez wszystkie zgrupowane w ten sposob obiekty.
Agregacja model pojęciowy i projektowy Osoba Grupa Osob Model pojęciowy 1…* 1 poziom Imie nazwisko GrupaOsob Osoba int poziom String imie Model projektowy Vector zapisani String nazwisko GrupaOsob grupa void dodaj()
Agregacja – implementacja class Program { public static void main(String[] args) { Osoba o1=new Osoba("",""), o2=new Osoba("",""); Vector v = new Vector(); v.add(o1); v.add(o2); GrupaOsob(v); } class GrupaOsob { public Vector zapisani; public GrupaOsob(Vector lista) { zapisani = lista; public void dodaj(Osoba o) { zapisani.add(o); o.grupa = this; class Osoba { public String imie; public String nazwisko; public GrupaOsob grupa; public Osoba(String imie, String nazwisko) { this.imie = imie; this.nazwisko = nazwisko; Pamiętanie- odniesień można zrealizować zarówno przy pomocy tablicy jak i kolekcji. Sposób jest zależny od liczności z jaka mamy do czynienia. Przy znanej liczbie lepiej jest zastosować tablice, przy nieznanej liczności musimy sięgać do kolekcji. Patrz wykład o asocjacjach.
Kompozycja model pojęciowy i projektowy Samochód Silnik Model pojęciowy Model rocznik 1 typ Samochód Silnik String model int rocznik String typ Silnik silnik Model projektowy
Kompozycja – implementacja Pamiętanie odniesień można zrealizować zarówno przy pomocy tablicy jak i kolekcji. Sposób jest zależny od liczności z jaka mamy do czynienia. Przy znanej liczbie lepiej jest zastosować tablice, przy nieznanej liczności musimy sięgać do kolekcji. Patrz wykład o asocjacjach. public class Program { public static void main(String[] args) { Samochod s=new Samochod(); Samochod.silnik=new Silnik("diesel"); } class Samochod { public Silnik silnik; public montujSilnik(Silnik s) { silnik = s; class Silnik { public int rocznik; public int pojemnosc; public String typ; public Silnik(String typ) { this.typ = typ;
Asocjacja kwalifikowana (1) { nazwa pliku jest unikatowa w ramach katalogu } 1 Plik * Katalog nazwa 1 0..1 Katalog nazwa pliku Plik Perspektywa pojęciowa - plik jest w ramach katalogu jednoznacznie identyfikowany przez nazwę. 1 Perspektywa projektowa - wskazanie na to, że katalog plików można zorganizować jako tablicę asocjacyjną lub słownik (przeszukiwanie za pomocą nazwy pliku). 2
Asocjacja kwalifikowana (2) Kwalifikator asocjacji może stanowić więcej niż jeden atrybut. Warunek - wartości tych atrybutów muszą pozwolić na jednoznaczną identyfikację obiektu w ramach pewnego zbioru obiektów (tutaj - w ramach zbioru kwadratów należących do jednej konkretnej tablicy, czyli jednego obiektu klasy Tablica). Tablica Kwadrat rząd kolumna 1 100 Tablica Kwadrat rząd kolumna 1 Asocjacja kwalifikowana, jak każda asocjacja, może posiadać atrybuty. Osoba imię nazwisko nr konta data założ. * Bank nazwa Osoba imię nazwisko Bank nr. konta * 0..1 nazwa data założ.
Asocjacja kwalifikowana modele pojeciowy i projektowy Uczelnia 1 1 Student Nr Indeksu Nazwa Imię Nazwisko Uczelnia Student String nazwa String imię Hashtable studenci String nazwisko String index
Asocjacja kwalifikowana - implementacja class Uczelnia { Hashtable studenci; public void dodajStudenta (String nrIndeksu, Student student) { studenci.put (nrIndeksu, student); } public void zlikwidujStudenta (String nrIndeksu) { studenci.remove(nrIndeksu); class Student { String nrIndeksu; String imie; String nazwisko;
Asocjacja n-arna Notacja Asocjacja n-arna to asocjacja, której wystąpienia łączą n obiektów, będących instancjami co najwyżej n klas: 3-arna - 3 obiekty (inna nazwa dla tej asocjacji to ternarna), 4-arna - 4 obiekty, itd. Dana klasa może pojawić się na więcej niż jednej pozycji w asocjacji. Asocjacja binarna ze swoją uproszczoną notacją i pewnymi dodatkowymi własnościami (takimi jak możliwość ustalania kierunku nawigowania, kwalifikatorów, związków agregacji czy kompozycji) jest specjalnym rodzajem asocjacji n-arnej (dla n=2). Asocjacja binarna i 2-arna są równoważne, nie istnieje między nimi różnica semantyczna, inny jest tylko sposób reprezentowania. Wymienione wyżej dodatkowe własności asocjacji binarnych są zabronione dla asocjacji n-arnych, gdzie n > 2. asocjacja 3-arna asocjacja 4-arna Notacja K1 K3 K1 nazwa asocjacji K3 K2 K2
Asocjacja n-arna; liczności Specyfikowanie liczności dla asocjacji n-arnych nie jest tak oczywiste, jak dla asocjacji binarnych i różni autorzy wygłaszają na ten temat różne zdania. UML odrzuciła poglądy, że liczność danej roli powinna być ustalana w odniesieniu do liczności pozostałych ról, traktowanych oddzielnie. Przyjęto zasadę, że liczność n-tej roli jest opisana przez zbiór możliwych wartości liczności, gdy sytuacja na n-1 końcach asocjacji jest ustalona. Np. dla ternarnej asocjacji łączącej klasy A,B i C liczność roli C specyfikuje, ile obiektów klasy C jest powiązanych z każdą możliwą parą obiektów klas A i B. Taka reguła jest zgodna z regułą przyjętą dla specyfikowania liczności asocjacji binarnych. Atrybuty Rok * sezon * Zespół Gracz * bramkarz Zapis Mecz gole nasze gole ich
Obejście asocjacji n-arnej Asocjacje n-arne mają sens wtedy, gdy do identyfikacji powiązania (n-arnego) potrzebne są wszystkie obiekty, tzn. gdy liczność każdej z ról jest “wiele”. W pozostałych przypadkach asocjację n-arną warto jest zastępować asocjacjami binarnymi, które są łatwiejsze do implementacji i wyposażone w dodatkowe własności, o których była mowa poprzednio. Niestety traci się informację o związku, łączącym grupę obiektów w pewną całość. K1 K3 K2 KA a1 a2 m1 A K1 K3 K2 KA a1 a2 m1 Asocjacja n-arna zostaje zamieniona na klasę i n asocjacji binarnych.
Reprezentuje związek zachodzący pomiędzy n obiektami. Asocjacja n-arna Reprezentuje związek zachodzący pomiędzy n obiektami. Student Sala Wykładowca Zajęcia * Przedmiot Data
Asocjacja n-arna cd.. Asocjacje n-arne przydatne są w przypadku obiektów powiązanych ze sobą licznościami wiele do wiele. Obejście asocjacji n-arnej poprzez dodanie klasy: Student Sala Wykładowca Zajęcia Data Przedmiot sprawdzObecnosc() 1 *
Implementacja Student Sala Wykładowca Zajęcia Data Przedmiot 1 * class Wykladowca { String imie; String nazwisko; String tytulNaukowy; } class student { String nrIndeksu; class sala { int numer; class Zajecia { Date data; String przedmiot; Wykladowca prowadzacy; Student[] studenci; Sala sala; boolean sprawdzObecnosc() { ... } Student Sala Wykładowca Zajęcia Data Przedmiot boolean sprawdzObecnosc() 1 *
Ograniczenia Ograniczenia specyfikują restrykcje nakładane na elementy modelu. Mogą stanowić wyrażenia języka naturalnego czy języka formalnego (np. OCL w UML), mogą też przyjmować postać formuły matematycznej lub fragmentu kodu (czy też pseudokodu). Notacja: są zawarte wewnątrz {} i umieszczane za elementem w klasie, lub poza klasą. Mogą też być umieszczane w komentarzu (przykład na następnej folii). ograniczenie statyczne Pracownik Pracownik String imię String nazwisko int pensja -int max_pensja -int max_podwyzka imię nazwisko pensja {<=10 000} {pensja <=10 000} {pensja nie wzrasta o więcej niż 300} Void zmień pensję (nowa) Ograniczenie dynamiczne - tu interesuje nas poprzedni stan elementu, na który jest nałożone ograniczenie. Czy powiedzie się próba zmiany pensji z 2500 na 5500? ograniczenie dynamiczne
Pracownik String imię String nazwisko int pensja -int max_pensja class Pracownik { private int max_pensja=10000; private int max_podwyzka=300; String imie, nazwisko; int pensja; void zmienPensje(int suma) throws PensjaException { if (suma>max_pensja) //ograniczenie statyczne throw new PensjaException("Pensja za duza"); if (suma>pensja+max_podwyzka) //dynamiczne throw new PensjaException("Podwyzka za duza"); pensja=suma; } import java.util.*; class Program { public Program() { Pracownik p=new Pracownik(); try { p.zmienPensje(2000); } catch (PensjaException exc) { System.out.println(exc); } class PensjaException extends Exception { public PensjaException(String przyczyna) { super(przyczyna); Pracownik String imię String nazwisko int pensja -int max_pensja -int max_podwyzka zmień pensję (nowa)