Projektowanie systemów informacyjnych
Ewa Stemposz, Kazimierz Subieta Instytut Podstaw Informatyki PAN, Warszawa
Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa
Wykład 8
Model obiektowy (5)
Zagadnienia
ADT
Delegacja Protytypy Role
Transformacje diagramu klas:
Podział poziomy klasy
Podział pionowy klasy
Realizacja struktur generalizacji/specjalizacji typu: disjoint
overlapping dynamic
Generalizacja wieloaspektowa
Abstrakcyjny typ danych
Abstrakcyjny typ danych jest bardzo bliski pojęciu klasy, której wystąpienia eksportują (niektóre) operacje, zaś ich struktura nie jest dostępna bezpośrednio dla operacji z zewnątrz.
ADT ogranicza kontekst, w którym odwołanie do obiektu może być użyte w programie.
ADT może odnosić się nie tylko do obiektów, ale również do wartości.
Z drugiej strony, ADT może być uważane za pojęcie znacznie węższe lub ortogonalne w stosunku do pojęcia klasa. W czystej postaci, ADT nie uczestniczy w związkach dziedziczenia, wystąpienia ADT nie posiadają tożsamości, nie można ich wzajemnie łączyć (powiązaniami), ani wykonywać operacji na zbiorze wystąpień ADT (brak odpowiednika ekstensji i metody klasy).
Abstrakcyjny typ danych (ADT) - pojęcie udostępniane w niektórych językach programowania oparte na założeniu, że typ struktury danych jest skojarzony z operacjami działającymi na elementach tego typu. Nie istnieje potrzeba i możliwość używania operacji nie należących do oferowanego zestawu; operacje są kompletne i wyłączne.
Bezpośredni dostęp do składowych takiej struktury danych nie jest możliwy.
Przykłady ADT
stos (z operacjami: pop, push, top, empty), pakiety obsługujące: mysz, CD ROM, grafikę, heap
Delegacja - alternatywa dla dziedziczenia
Klasa “Stos” dziedziczy niepotrzebne operacje z klasy
“Lista”
Obiekt klasy Stos składa się z podobiektu zawartość, członka klasy Lista.
Anomalia dziedziczenia jest usunięta. Obsługa obiektu Stos jest (częściowo) oddelegowana do obiektu Lista.
push pop
zawartość push pop
Operacje na obiekcie są oddelegowane do innego obiektu.
Delegacja to alternatywa dla dziedziczenia: w tym przypadku
dziedziczenie, czyli importowanie inwariantów zachodzi dynamicznie (w czasie działania programu) w ramach wystąpień klas (obiektów). Część własności danego obiektu (np. metody) jest przechowywana w innej klasie.
Stos
Lista pierwszy następny ostatni dodaj pobierz pierwszy
następny ostatni dodaj pobierz
Lista Stos
...
...
Prototypy (1)
Dowolny obiekt może stać się prototypem. Pod pojęciem prototypu rozumie się zarówno obiekt jako wzorzec dla innego obiektu (przy tworzeniu nowego obiektu), jak i to, że informacje z obiektu-prototypu są dynamicznie (w czasie działania programu) dostępne dla innych obiektów.
W ten sposób uzyskuje się jednorodność i zminimalizowanie środków: potrzebne są wyłącznie obiekty oraz wskaźniki (powiązania) od obiektów do ich prototypów. Te powiązania między obiektami są przechodnie; obiekty mogą być powiązane w hierarchię.
Koncepcja prototypów jest dość uniwersalna i pozwala modelować klasy, dziedziczenie, dziedziczenie wielokrotne i role.
Pojęcie ściśle powiązane z delegacją.
Koncepcja wizjerów idzie dalej - wskaźnik prowadzący do obiektu prototypu może być dodatkowo zaopatrzony w filtry, ustalające, co ma być importowane.
Prototypy (2)
Podstawowym argumentem zwolenników prototypów jest zmniejszenie liczby pojęć.
Koncepcja prototypów jest nieunikniona, jeżeli ktoś chciałby implementować dynamiczne role obiektów. Pojęcie klasy, jako przechowalni inwariantów, ma jednak ogromne znaczenie dla modelowania pojęciowego, stąd pojęcia prototypu i klasy uzupełniają się.
Prototyp
Łapy: 4 Ogon: 1 Uszy:2 Oczy:2
Ulubieniec
Szczepienie()
Wabi_się: Rex Rasa: jamnik
Płeć: M
Pies Wabi_się: Mrusia
Rasa: nieznana Płeć: Ż
Kot
Uszy:1
Języki prototypowe (np. Self) nie wprowadzają pojęcia klasy.
Obiekt może dziedziczyć cokolwiek z jakiegokolwiek innego obiektu.
Role
Student jest Osobą Źle!
Osoba
staje się
StudentemOsoba
staje się
StudentemOsoba Kowalski
Osoba Kowalski
Właścicie l psa
Pracownik Student Pacjent
Członek klubu golfowego Kibi
c Legii Podatnik
Rola importuje wartości atrybutów obiektu oraz inwarianty jego klasy
Rola może mieć własne (dodatkowe) atrybuty
Rola może należeć do własnej klasy
Każdy obiekt w czasie swojego życia może nabywać i tracić wiele ról, nie zmieniając swojej tożsamości. Role zmieniają się dynamicznie.
Role - przykład
NAZWISKO ROK_UR Wiek()
Kowalska: pracownik
Nowak: pracownik+student Abacka:
Nowacki: student
Rola importuje nie tylko inwarianty swojej klasy, lecz także wartości atrybutów swojego obiektu oraz inwarianty jego klasy.
NAZWISKO = Nowacki ROK_UR = 1940
NAZWISKO = Abacka ROK_UR = 1948 NAZWISKO = Nowak
ROK_UR = 1951
ZAROBEK DZIAŁ
ZarobekNetto() ZmieńZarobek(...) NAZWISKO = Kowalska
ROK_UR = 1975
NR_INDEKSU INDEKS
WpiszOcenę(...) ObliczŚredniąOcen()
:PRACOWNIK ZAROBEK = 2000 DZIAŁ = zabawki
:PRACOWNIK ZAROBEK = 2500
DZIAŁ = zabawki NR_INDEKSU = 223344 INDEKS = ...
NR_INDEKSU = 556677 INDEKS = ...
rola
OSOBA
:OSOBA
:OSOBA :OSOBA :OSOBA
PRACOWNIK
STUDENT
:STUDENT :STUDENT
{overlapping}
Podział poziomy klasy (podział ekstensji klasy)
K1
K2
a1 a2 m1 m2
a K21
a1 ? a2 ? m1 ? m2 ?
K22
a1 ? a2 ? m1 ? m2 ?
a ? K1 a ?
Przykład
Osoba
imię nazwisko nazwa szkoły
wysokość emerytury pensja
podaj nazwisko podaj szkołę zmień emeryturę zmień pensję
Firma
nazwa 0..1
zatrudnia
*
Uczeń
imię nazwisko nazwa szkoły podaj nazwisko podaj szkołę
Emeryt
imię nazwisko
wysokość emerytury podaj nazwisko zmień emeryturę
Pracownik
imię nazwisko pensja
podaj nazwisko zmień pensję
Firma
nazwa
* 1
Osoba
imię nazwisko
podaj nazwisko
zatrudnia
Podział pionowy klasy (podział inwariantów klasy)
K1
K2
a1 a2 a3 m1 m2 m3
a K21
a1 m2 m3
K22
a2 a3 m1
K1
Przykład
Firma
nazwa adres firmy
telefon firmy [1..*]
imię dyrektora nazwisko dyrektora adres dyrektora telefon dyrektora zmień adres firmy podaj telefon dyrektora
Klient
*
zlecił
1..*
Osoba
imię nazwisko adres telefon
podaj telefon
Firma
nazwa adres
telefon [1..*]
zmień adres
Klient
1..*
* zlecił
np.
1 0..1 dyrektor a
Realizacja struktur generalizacji/specjalizacji (1)
Osoba {abstract}
Student Pracownik
Osoba
Student Pracownik
0..1 {xor} 0..1
perspektywa pojęciowa: generalizacja/specjalizacja perspektywa projektowa: dziedziczenie
perspektywa projektowa: kompozycja
Kowalski Nowak
Nowak:Student
Kowalski:Pracownik
Nowak:Osoba
Nowak:Student
Kowalski:Osoba
Kowalski:Pracownik
Zamiast kompozycji można tu użyć zarówno agregacji, jak i zwykłej asocjacji.
Klasa Osoba jest klasą abstrakcyjną.
Klasa Osoba przestaje być klasą abstrakcyjną.
Realizacja struktur generalizacji/specjalizacji (2)
Osoba {abstract}
Student Pracownik
Kowalski Nowak
{overlapping}
Abacki
perspektywa pojęciowa
perspektywa pojęciowa czy projektowa ?
Osoba {abstract}
Student Pracownik
Student/Pracownik
Sytuację, gdy klasa będąca efektem wielokrotnej specjalizacji (termin ?) (tu: Student/Pracownik) sama nie posiada klas specjalizowanych, prawdopodobnie byłoby lepiej modelować poprzez wykorzystanie ograniczenia {overlapping}, nie wywołując dzięki temu zbyt mocnego skojarzenia z dziedziczeniem
wielokrotnym, czyli perspektywą projektową. Student/Pracownik na zlecenie
Realizacja struktur generalizacji/specjalizacji (2)
Osoba
Student Pracownik
0..1 0..1
Nowak:Osoba
Nowak:Student
Kowalski:Osoba
Kowalski:Pracownik Abacki:Osoba
Abacki:Student
Abacki:Pracownik
Realizacja dziedziczenia {overlapping}: perspektywa projektowa
Osoba {abstract}
Pracownik Student/Pracownik Student
Realizacja struktur generalizacji/specjalizacji (4)
Osoba {abstract}
Projektant Analityk
Menażer
«dynamic»
Osoba
Projektant Analityk
Menażer
{xor}
0..1 0..1 0..1
Zachowując realizację z wykorzystaniem dziedziczenia, przy każdej zmianie specjalizacji Osoby powstaje nowy obiekt jednej z trzech podklas: Menażer, Analityk czy Projektant. Własności odziedziczone z klasy Osoba są każdorazowo przepisywane.
W przypadku realizacji z wykorzystaniem kompozycji, usuwany jest obiekt związany ze starą specjalizacją, tworzony jest obiekt przechowywujący własności związane z nową specjalizacją oraz tworzone jest powiązanie między nowym obiektem a obiektem klasy Osoba, przechowującym dane osobowe. Klasa Osoba nie może być klasą abstrakcyjną.
perspektywa pojęciowa
perspektywa projektowa
Pracownik godzinowy nie emerytowany
Generalizacja wieloaspektowa
Osoba
status
płacowy stosunek
do emerytury
Bywa konieczna, ale często komplikuje pielęgnację oprogramowania.
Przykład:
Pracownik godzinowy
Pracownik etatowy
Pracownik na zlecenie
Osoba nie emerytowana
Osoba emerytowana
Osoba
specjalizacje wg płac
specjalizacje wg emerytury Pracownik
perspektywa pojęciowa
Emeryt
Delegacja z użyciem ról
Osoba
Pracownik Emeryt
Specjalizacje wg płac
Specjalizacje wg emerytury Osoba
Pracownik godzinowy
Pracownik etatowy
Pracownik na zlecenie
Osoba nie emerytowana
Osoba emerytowana Pracownik
perspektywa projektowa
Emeryt
Użycie dziedziczenia i delegacji
Dziedziczenie Delegacja
Osoba
Emeryt
Specjalizacje wg płac
Specjalizacje wg emerytury Osoba
Pracownik godzinowy
Pracownik etatowy
Pracownik na zlecenie
Osoba nie emerytowana
Osoba emerytowana Pracownik
perspektywa projektowa
Emeryt
Zagnieżdżona generalizacja (1)
Pracownik {abstract}
status płacowy
stosunek do emerytury
stosunek do emerytury
stosunek do emerytury
Pracownik godzinowy nie
emerytowany
Pracownik godzinowy emerytowany
Pracownik etatowy nie emerytowany
Pracownik etatowy emerytowany
Pracownik na zlecenie nie emerytowany
Pracownik na zlecenie emerytowany Pracownik godzinowy
{abstract}
Pracownik etatowy {abstract}
Pracownik na zlecenie {abstract}
perspektywa projektowa
Zagnieżdżona generalizacja (2)
Pracownik {abstract}
stosunek do emerytury
status płacowy
status płacowy
Pracownik emerytowany
godzinowy
Pracownik emerytowany
etatowy
Pracownik emerytowany
na zlecenie
Pracownik nie emerytowany
godzinowy
Pracownik nie emerytowany
etatowy
Pracownik nie emerytowany
na zlecenie Pracownik emerytowany
{abstract}
Pracownik nie emerytowany {abstract}
perspektywa projektowa
Zalecenia
Jeżeli klasa ma kilka nadklas, wszystkie jednakowo ważne, najlepiej użyć delegacji, która zachowuje symetrię modelu.
Jeżeli jedna nadklasa wyraźnie dominuje, ma zdecydowanie więcej cech niż pozostałe, inne wydają się być mniej ważne lub może powodować wąskie gardło w wydajności, tę klasę najlepiej zaimplementować poprzez dziedziczenie, zaś pozostałe przez delegację.
Jeżeli liczba kombinacji klas jest mała, można rozpatrywać zagnieżdżoną generalizację.
Przy zagnieżdżonej generalizacji, najważniejszy czynnik - o czym może zaświadczać np. zdecydowanie większa liczba cech - powinien być pierwszym kryterium podziału;
pozostałe dalej, w hierarchii ważności.
Unikać zagnieżdżonych generalizacji, jeżeli duża ilość kodu musi być powtórzona.