1
Podstawy programowania II
dr inż. Paweł Róg
2
Zagadnienia
■
Co to jest paradygmat programowania?
Programowanie imperatywne
Programowanie funkcyjne
Programowanie logiczne
Programowanie obiektowe
■
Cechy programowania obiektowego
Abstrakcja
Dziedziczenie
Dynamiczne wiązania i polimorfizm
■
Język UML
Geneza
Perspektywy
Diagramy
3
Co to jest paradygmat programowania?
■
„przyjęty sposób widzenia rzeczywistości w danej
dziedzinie, doktrynie itp.” lub „zespół form fleksyjnych
(deklinacyjnych lub koniugacyjnych), właściwy
danemu typowi wyrazów; wzorzec, model deklinacyjny
lub koniugacyjny” (Słownik języka polskiego PWN)
■
παράδειγμα (gr.) - wzorzec, przykład
■
zbiór mechanizmów, jakich programista używa, pisząc
program, i to, jak ów program jest następnie
wykonywany przez komputer
■
Paradygmat programowania to ogół oczekiwań
programisty wobec języka programowania
i komputera, na którym będzie działał program
4
Wybrane paradygmaty programowania
■
Programowanie imperatywne
■
Programowanie funkcyjne
■
Programowanie w logice (programowanie
logiczne)
■
Programowanie obiektowe
5
Programowanie imperatywne
■
Programowanie imperatywne to najbardziej pierwotny sposób
programowania, w którym program postrzegany jest jako ciąg
poleceń dla komputera
Obliczenia rozumiemy tu jako sekwencję poleceń zmieniających
krok po kroku stan maszyny, aż do uzyskania oczekiwanego
wyniku.
Stan maszyny należy z kolei rozumieć jako zawartość całej
pamięci oraz rejestrów i znaczników procesora.
Ten sposób patrzenia na programy związany jest ściśle z budową
sprzętu komputerowego o architekturze von Neumanna, w którym
poszczególne instrukcje (w kodzie maszynowym) to właśnie
polecenia zmieniające ów globalny stan.
Języki wysokiego poziomu — takie jak Fortran, Algol, Pascal, Ada
lub C — posługują się pewnymi abstrakcjami, ale wciąż
odpowiadają paradygmatowi programowania imperatywnego.
Przykładowo, instrukcje podstawienia działają na danych
pobranych z pamięci i umieszczają wynik w tejże pamięci, zaś
abstrakcją komórek pamięci są zmienne.
6
Program w języku imperatywnym
program pierwszy;
var i, n, s: integer;
begin
read(n);
s := 1;
for i := 2 to n do
s := s * i;
write(s)
end.
7
Programowanie funkcyjne
■
W programowaniu funkcyjnym program to po prostu złożona
funkcja (w sensie matematycznym), która otrzymawszy dane
wejściowe wylicza pewien wynik
Zasadniczą różnicą w stosunku do innych paradygmatów
jest brak stanu maszyny: nie ma zmiennych, a co za tym
idzie nie ma żadnych efektów ubocznych.
Nie ma też imperatywnych z natury, tradycyjnie rozumianych
pętli (te wymagają np. zmiennych do sterowania ich
przebiegiem).
Konstruowanie programów to składanie funkcji, zazwyczaj
z istotnym wykorzystaniem rekurencji. Charakterystyczne
jest również definiowanie funkcji wyższego rzędu, czyli
takich, dla których argumentami i których wynikami mogą
być funkcje (a nie tylko „proste” dane jak liczby lub napisy).
8
Program w języku funkcyjnym
(DEFINE (suma m n)
(IF (> m n)
0
(+ m (suma (+ m 1) n))
)
)
9
Programowanie w logice
■
Na program składa się zbiór zależności
(przesłanki) i pewne stwierdzenie (cel)
Wykonanie programu to próba udowodnienia celu
w oparciu o podane przesłanki.
Obliczenia wykonywane są niejako „przy okazji”
dowodzenia celu.
Podobnie jak w programowaniu funkcyjnym, nie
„wydajemy rozkazów”, a jedynie opisujemy, co
wiemy i co chcemy uzyskać.
10
Program w języku logicznym
ojciec(jan, jerzy).
ojciec(jerzy, janusz).
ojciec(jerzy, józef).
dziadek(X, Z) :- ojciec(X, Y), ojciec(Y, Z).
?- dziadek(X, janusz).
11
Programowanie obiektowe
■
W programowaniu obiektowym program to zbiór
porozumiewających się ze sobą obiektów, czyli jednostek
zawierających pewne dane i umiejących wykonywać na nich pewne
operacje
Ważną cechą jest tu powiązanie danych (czyli stanu)
z operacjami na nich (czyli poleceniami) w całość, stanowiącą
odrębną jednostkę — obiekt.
Cechą nie mniej ważną jest mechanizm dziedziczenia, czyli
możliwość definiowania nowych, bardziej złożonych obiektów, na
bazie obiektów już istniejących.
■
Zwolennicy programowania obiektowego uważają, że ten paradygmat
dobrze odzwierciedla sposób, w jaki ludzie myślą o świecie
Nawet jeśli pogląd ten uznamy za przejaw pewnej egzaltacji, to
niewątpliwie programowanie obiektowe zdobyło ogromną
popularność i wypada je uznać za paradygmat obecnie
dominujący.
12
Program w języku obiektowym
public class Hello {
public static void main(String[] args)
System.out.println("Hello, I am James B.");
}
}
13
Konkretny język programowania
ucieleśnia jeden lub więcej
paradygmatów
■
Fortran, Pascal i C to języki pozwalające
stosować paradygmat programowania
imperatywnego. Mówi się wręcz, że są to języki
imperatywne.
■
Java bądź C# to z kolei języki obiektowe,
w których typowe programowanie imperatywne
zostało mocno ograniczone.
■
Natomiast C++ jest językiem zarówno
obiektowym, jak i imperatywnym.
14
Programowanie obiektowe
■
Idea programowania zorientowanego obiektowo
swoimi korzeniami sięga języka Simula 67,
zaprojektowanego przez Ole-Johana Dahla
i Kristena Nygaarda jako język do zastosowań
symulacyjnych. W pełni rozwinięta została
w Smalltalku 80, zaprojektowanym jako język
„czysto obiektowy”, o jednolitej, klarownej
składni. Prawdziwa powszechność i sukces
komercyjny przyszły natomiast wraz z językiem
C++, a później Java.
15
Programowanie obiektowe
■
Język obiektowy musi posiadać trzy
podstawowe cechy:
Abstrakcyjne typy danych.
Dziedziczenie.
Dynamiczne wiązania wywołań metod z metodami
(ściślej: z definicjami metod).
16
Klasy, obiekty i podklasy
■
Abstrakcyjne typy danych w językach obiektowych zwykle
nazywane są klasami.
■
Instancje klas są nazywane obiektami.
■
Klasa, która zdefiniowana została poprzez dziedziczenie z innej
klasy, nazywana jest klasą pochodną bądź podklasą.
■
Klasa, z której wywiedziono podklasę, nazywana jest klasą
bazową lub nadklasą.
■
Podprogramy, które definiują operacje na obiektach klasy, to
metody.
■
Odwołania do metod czasem nazywa się komunikatami.
■
Zbiór wszystkich metod danego obiektu nazywany jest
protokołem komunikatów tegoż obiektu.
17
O obiektach słów parę
1.Wszystko jest obiektem
2.Program jest zbiorem obiektów, które poprzez
wysyłanie komunikatów mówią sobie nawzajem, co
robić
3.Każdy obiekt posiada własną pamięć, na która
składają się inne obiekty
4.Każdy obiekt posiada swój typ
5.Wszystkie obiekty danego typu mogą otrzymywać
te same komunikaty
Obiekt ma stan, zachowanie i tożsamość
Obiekt ma stan, zachowanie i tożsamość
18
Obiekt posiada interfejs
Żarówka
zapal()
zgaś()
rozjaśnij()
przyciemnij()
Nazwa typu
Interfejs
Zarowka zr = new Zarowka();
zr.zapal();
19
Obiekt dostarcza usługi
■
Program świadczy pewne usługi dla użytkownika,
realizując je przy pomocy usług oferowanych przez
inne obiekty
■
Naszym celem jest stworzenie grupy obiektów (lub
odszukanie istniejącej biblioteki zawierającej takie
obiekty!) udostępniających usługi, które optymalnie
nadają się do rozwiązania problemu
■
Obiekty powinny się cechować wysoką spójnością
– dostarczać wyspecjalizowane usługi – realizować
dobrze jedno zadanie, nie robić zbyt wiele
20
Dziedziczenie
Figura
narysuj()
wymaż()
przesuń()
zwróćKolor()
ustawKolor()
Okrąg
Trójkąt
Kwadrat
odwróćPoziomo()
odwróćPionowo()
21
Przesłonięcie
Figura
narysuj()
wymaż()
przesuń()
zwróćKolor()
ustawKolor()
Okrąg
Trójkąt
Kwadrat
narysuj()
wymaż()
narysuj()
wymaż()
narysuj()
wymaż()
22
Ukrywanie implementacji
■
Twórcy klas (ang. class creators)
i programiści-klienci (ang. client
programmers)
■
Programista-klient nie powinien dotykać
delikatnego wnętrza obiektu
■
Projektant biblioteki powinien móc wymienić
wewnętrzne mechanizmy klasy, nie psując
programu programisty-klienta
■
Poziomy dostępu: public, private i protected
23
Sterowanie dostępem
■
W najprostszym przypadku klasa dziedziczy wszystkie byty
swojej nadklasy.
■
Sterowanie dostępem pozwala programiście na ukrycie części
typu abstrakcyjnego przed klientem poprzez zadeklarowanie
pewnych bytów jako publiczne (public), a innych jako prywatne
(private).
■
Trzeciej kategorii sterowania dostępem, chroniony (protected),
używa się, aby umożliwić dostęp do bytów klasom pochodnym,
a jednocześnie zabronić dostępu do nich klientom.
■
Klasa pochodna może modyfikować dziedziczone metody.
Zmodyfikowana metoda ma tę samą nazwę; często także ten
sam protokół. Mówi się wówczas o przedefiniowaniu
odziedziczonej metody
24
Dziedziczenie pojedyncze i wielokrotne
■
Jeżeli nowa klasa jest podklasą tylko jednej
klasy bazowej, to taki proces derywacji
nazywany jest dziedziczeniem pojedynczym.
■
Jeżeli nowa klasa ma więcej niż jedną
nadklasę, to proces nazywamy dziedziczeniem
wielokrotnym.
25
Metody i klasy abstrakcyjne
■
Zdarza się, że klasa jest na tyle wysoko w hierarchii
dziedziczenia, że nie ma sensu tworzyć dla niej
instancji.
■
Podobnie, nie ma sensu implementować metody,
która jest zbyt wysoko w hierarchii (jako że została już
zaimplementowana w podklasach).
■
Taka metoda nazywana jest metodą abstrakcyjną.
■
Klasa, która zawiera przynajmniej jedną metodę
abstrakcyjną, nazywana jest klasą abstrakcyjną.
26
Metody i zmienne obiektu i klasy
■
Klasy mogą mieć metody i zmienne instancyjne lub metody
i zmienne klasowe.
■
W tym pierwszym przypadku każdy obiekt z danej klasy ma
swój własny zbiór instancji zmiennych, w których
przechowywany jest stan obiektu.
■
W drugim przypadku, metody i zmienne przynależą do całej
klasy i w klasie jest tylko jedna ich kopia. Mówi się
o metodach/zmiennych klasowych lub statycznych.
■
Metody instancyjne są zazwyczaj przechowywane w jednym
egzemplarzu (tak jak statyczne), ale wywołać je można tylko za
pomocą instancji obiektu.
■
Wywołanie metody statycznej nie wymaga powoływania do
życia instancji obiektu.
27
Polimorfizm i dynamiczne wiązania
■
Zmienne typu klasy bazowej mogą odwoływać
się także do obiektów dowolnej podklasy tejże
klasy bazowej.
■
Nadklasa może definiować metody, które są
przedefiniowywane przez jej podklasy.
■
Kiedy taka przedefiniowana metoda jest
wywoływana przez zmienną klasy bazowej, to
wywołanie to jest dynamicznie wiązane
z właściwą metodą.
■
Jest to rodzaj polimorfizmu: dynamiczne
wiązanie wywołań z definicjami metod.
28
Polimorfizm
Ptak
poruszaj()
SterownikPtaka
Pingwin
Gęś
poruszaj()
poruszaj()
przemieść()
29
Czy wszystko jest obiektem?
■
W czystym modelu obliczeń zorientowanych obiektowo wszystkie
typy są klasami.
■
Nie ma rozróżnienia pomiędzy klasami predefiniowanymi w języku
a klasami definiowanymi przez użytkownika.
■
Wszystkie obliczenia realizowane są poprzez przekazywanie
komunikatów, czyli wywołania metod.
■
Jest to rozwiązanie eleganckie, ale nawet proste operacje muszą być
wówczas wykonywane przy użyciu mechanizmu przekazywania
komunikatów.
■
Jedną z alternatyw jest zachowanie imperatywnego modelu typów
i dodanie modelu obiektowego, tak jak np. w C++. To bywa
kłopotliwe.
■
Inny pomysł to imperatywna struktura typów dla prostych typów
skalarnych, a obiektowa dla pozostałych (np. w Javie). To również
bywa mylące...
30
Czy podklasy są podtypami?
■
Innymi słowy, czy można powiedzieć, że obiekt z podklasy jest też
obiektem jej klasy bazowej?
■
Przykład: Mamy klasę zwierzę i dwie podklasy z niej wywiedzione:
pies i kot. Czy zatem każdy obiekt typu pies jest również obiektem
typu zwierzę? A co z kotem...?
■
Owa relacja „bycia obiektem nadklasy” gwarantowałaby, że wszędzie
tam, gdzie może pojawić się obiekt z klasy bazowej, może się
również pojawić (bez wystąpienia błędu typu) obiekt z podklasy.
■
Wywiedziona klasa może być nazwana podtypem, jeżeli jej obiekty
są w powyższej relacji z klasą bazową.
■
Podklasa ma w tej sytuacji ograniczone pole manewru: może jedynie
dodawać zmienne i metody oraz przedefiniowywać dziedziczone
metody w sposób zapewniający zgodność typów.
■
Relacje bycia podtypem i dziedziczenia nie są tożsame (do tego
jeszcze wrócimy).
31
Sprawdzanie zgodności typów i polimorfizm
■
Polimorfizm rozumiemy tu jako użycie polimorficznego wskaźnika
(referencji) do wywołania metody, która została przedefiniowana w
jednej z klas pochodnych.
■
Mówi się także, że metoda została nadpisana.
■
Owa polimorficzna zmienna (wskaźnik lub referencja) jest typu klasy
bazowej. W klasie tej znajduje się przynajmniej deklaracja protokołu
wołanej metody, przedefiniowanej następnie w klasie pochodnej.
■
Zmienna polimorficzna może wskazywać na obiekty zarówno klasy
bazowej, jak i pochodnej. Stąd konkretnego typu wskazywanego
obiektu nie da się określić statycznie.
■
Wiązanie wywołań realizowanych za pomocą zmiennych
polimorficznych z metodami musi się zatem odbywać dynamicznie.
■
Kiedy następuje sprawdzenie zgodności typów dla takiego
wywołania?
■
W języku silnie typowanym sprawdzenie powinno być statyczne. W
konsekwencji trzeba narzucić istotne ograniczenia, np.
przedefiniowana metoda musi zachować taki sam protokół.
■
Alternatywą jest dynamiczne sprawdzanie zgodności typów, czyli
wykonywane dopiero w chwili, gdy następuje wywołanie.
32
Dziedziczenie pojedyncze i wielokrotne
■
Czy język pozwala na dziedziczenie wielokrotne?
■
Jeśli tak, to jak rozstrzygamy odwołania do bytów (o takiej
samej nazwie) mających definicje w dwóch klasach
bazowych?
■
Rozstrzyganie takich wieloznaczności może być jawne, jak
np. w C++ za pomocą operatora zakresu ::.
■
Jeśli ta sama zmienna jest dziedziczona z klasy położonej
o dwa poziomy wyżej w hierarchii dziedziczenia za
pośrednictwem dwóch klas bazowych, to czy dziedziczone
jest jedno wcielenie, czy dwa?
33
■
Załóżmy, że klasa A zawiera pole x:
class A {
...
int x;
...
};
■
Dwie klasy, B1 i B2, są podklasami klasy A, dziedzicząc pole x:
class B1 : A {...};
class B2 : A {...};
■
Kolejna klasa, powiedzmy C, jest podklasą dziedziczącą po B1
i B2:
class C : B1, B2 {...};
■
Ile pól x jest zatem w klasie C?
34
Alokacja i dealokacja obiektów
■
Załóżmy, że:
Klasa B jest podklasą i podtypem klasy A.
Zmienna xb jest typu B.
Zmienna xa jest typu A.
■
Podstawienie „xa := xb” jest zatem prawidłowe.
■
Zauważmy, że obiekt xb jest większy niż obiekt xa (gdyż może mieć
dodatkowe pola).
■
Co zrobić, jeśli obiekt xa jest na stosie i niemożliwe jest powiększenie
zaalokowanego dla niego obszaru pamięci?
■
Drugie pytanie, związane z pamięcią: Czy obiekty alokowane na
stercie są dealokowane jawnie czy niejawnie?
■
Zauważmy, że dla obiektów alokowanych na stosie ta kwestia nie jest
istotna: zachowują się one tak samo jak zwykłe zmienne lokalne,
alokowane przy wejściu do podprogramu i dealokowane przy wyjściu.
35
Wiązanie statyczne i dynamiczne
■
Czy wiązanie wywołań z metodami zawsze jest
dynamiczne?
■
Innymi słowy — czy tam, gdzie to możliwe,
kompilator wiąże wywołania z metodami
statycznie?
■
Być może programista powinien mieć
możliwość wskazania, o jakie wiązanie chodzi.
36
Implementacja konstrukcji obiektowych
■
Dwa zasadnicze problemy:
Alokacja pamięci dla zmiennych
instancyjnych.
Dynamiczne wiązanie wywołań z metodami.
37
Przechowywanie danych instancyjnych
■
Zmienne należące do instancji obiektu są
przechowywane w rekordzie instancyjnym.
■
Jako że jego struktura jest statyczna, jest
tworzona w czasie kompilacji.
■
W czasie wykonania struktura ta używana jest
jako wzorzec do tworzenia danych w
instancjach.
■
Podklasy rozszerzają strukturę rekordu
instancyjnego.
38
Dynamiczne wiązanie wywołań z metodami
■
Metody wiązane statycznie nie wymagają
obsługi w rekordzie instancyjnym.
■
Metody wiązane dynamicznie, które mogą być
wywoływane z danej klasy, są zapisane
w tablicy metod wirtualnych (określanej zwykle
mianem vtable).
■
Rekord instancyjny każdego obiektu zawiera
wskaźnik do vtable.
■
Podstawienia pod zmienną polimorficzną
muszą dodatkowo ustawiać odpowiednio ów
wskaźnik
39
Wielokrotne wykorzystanie
implementacji
■
Kompozycja – umieszczenie obiektów innych
klas wewnątrz nowej klasy (tworzenie
obiektu składowego)
■
Dziedziczenie – utworzenie nowej klasy na
podstawie klasy już istniejącej – nowa klasa
przejmuje właściwości klasy bazowej, może
je modyfikować i dodawać nowe
40
Obiektowe i strukturalne metody analizy
■
Metody strukturalne
Tradycyjne, rozwijane od lat 60-tych XX w.
Wyróżniają w analizowanym systemie dwie składowe:
➔
Pasywne (dane)
➔
Aktywne (operacje)
■
Metody obiektowe
Pojawiły się w latach 80-tych XX w., nadal intensywnie
rozwijane
Wyróżniają w analizowanym systemie składowe (klasy
obiektów), które łączą w sobie możliwość
przechowywania danych (stan obiektu) oraz
wykonywania pewnych operacji (metody obiektu).
41
Analiza strukturalna
■
Rozpoczyna się od budowy dwóch różnych
modeli systemu:
Modelu danych (pasywna część systemu)
Modelu funkcji (aktywna część systemu)
■
Te dwa modele są następnie integrowane:
powstaje model przepływu danych
42
Analiza strukturalna
■
Budowa dwóch różnych modeli systemu
ułatwia zrozumienie jego różnorodnych
aspektów
■
Integracja dwóch różnych modeli może być
bardzo trudna
■
Skuteczne, jeśli jeden z aspektów (pasywny
lub aktywny) jest wyraźnie bardziej istotny
■
Mało skuteczne, jeśli system ma realizować
skomplikowane funkcje na złożonych danych
43
Analiza obiektowa
■
Obiekt posiada:
Tożsamość (da się jednoznacznie wyróżnić w
ramach systemu)
Stan
Zachowanie
■
Obiekty są grupowane w klasy złożone
z obiektów o podobnych stanach i
zachowaniu
44
Analiza obiektowa
■
Przyczyny popularności:
Umożliwia analizę złożonych systemów
Ułatwia implementację systemów w obiektowych
językach programowania
Model obiektowy można zaimplementować np.
stosując języki proceduralne i relacyjną bazę
danych
Trudna
jest
implementacja
modelu
strukturalnego
w obiektowych
językach
programowania
45
Notacje obiektowe
■
Lata 80-te XX w. – pojawienie się obiektów
■
1988 – 1992 – burzliwy rozwój metod analizy
obiektowej: OMT (Rumbaugh, 1991), OOA i OOD
(Coad i Yourdon, 1994), OOAD (Booch, 1994),
OOSE (Jacobson, 1992) ...
■
1994 – 1995 – Grady Booch i Jim Rumbaugh
pracują nad Metodą Zunifikowaną
■
1996 – Grady Booch, Jim Rumbaugh i Ivar
Jacobson pracują nad UML
■
1997 – wersja 1.0 UML
46
UML
■
Zunifikowany Język Modelowania (ang. Unified
Modeling Language – UML) jest następcą obiektowych
metod analizy i projektowania, które pojawiły się na
przełomie lat osiemdziesiątych i dziewięćdziesiątych.
■
Jest standardem OMG (Object Managment Group) –
organizacji standaryzującej w dziedzinie technik
obiektowych.
■
Jest językiem modelowania, a nie metodą. Większość
metod składa się z języka modelowania (notacja
graficzna) i procesu (kroki projektowania i tworzenia
oprogramowania).
■
Jest powiązany z Rational Unified Process (RUP)
47
Perspektywy UML
Perspektywa
projektowa
Perspektywa
implementacyjna
Perspektywa
procesowa
Perspektywa
wdrożeniowa
Perspektywa
przypadków
użycia
Słownictwo
Funkcjonalność
Zachowanie
Efektywność
Skalowalność
Przepustowość
Scalanie systemu
Zarządzanie konfiguracją
Opracowanie układu systemu
Rozmieszczenie
Dostarczenie
Instalacja
48
Perspektywa przypadków użycia
W perspektywie tej bierze się pod uwagę
zachowanie systemu widziane oczami
użytkowników,
analityków
i
osób
wykonujących testy. Nie definiuje się
rzeczywistej organizacji systemu, a opisuje
się
czynniki
wpływające
na
kształt
architektury systemu. W UML aspekty
statyczne tej perspektywy wyraża się za
pomocą diagramów przypadków użycia, a
dynamiczne
za
pomocą
diagramów
interakcji, diagramów stanu i diagramów
czynności
49
Perspektywa projektowa
W perspektywie tej kładzie się nacisk na klasy,
interfejsy i kooperacje, które razem składają
się na słownictwo danego zadania i na
rozwiązanie tego zadania. Perspektywa ta
pomaga
w zapisywaniu
wymagań
funkcjonalnych, czyli usług, które system
powinien udostępniać swoim użytkownikom.
W UML aspekty statyczne tej perspektywy
wyraża się za pomocą diagramów klas i
diagramów obiektów, a dynamiczne za
pomocą diagramów interakcji, diagramów
stanów i diagramów czynności.
50
Perspektywa procesowa
W perspektywie tej zwraca się uwagę na wątki
i procesy, które kształtują mechanizmy
współbieżności i synchronizacji w systemie.
Dotyczy
ona
głównie
efektywności,
skalowalności i przepustowości systemu.
W UML aspekty statyczne i dynamiczne tej
perspektywy są przedstawiane na takich
samych rodzajach diagramów jak w
przypadku perspektywy projektowej, z tą
tylko różnicą, że główny nacisk kładzie się na
klasy aktywne, które reprezentują procesy i
wątki.
51
Perspektywa implementacyjna
W
perspektywie
tej
znaczenie
mają
komponenty i pliki, użyte do scalenia i
udostępnienia systemu fizycznego. Wiąże się
ona
z
zarządzaniem
konfiguracją
poszczególnych wersji systemu, złożonych z
rozmaitych niezależnych komponentów i
plików, które można zepolić na wiele
sposobów, aby otrzymać działający system.
W UML aspekty statyczne tej perspektywy
wyraża
się
za
pomocą
diagramów
komponentów, a dynamiczne za pomocą
diagramów interakcji, diagramów stanów i
diagramów czynności.
52
Perspektywa wdrożeniowa
W perspektywie tej kładzie się nacisk na węzły,
składające się na sprzęt, na którym system
będzie uruchamiany. Wiąże się ona głównie
z rozmieszczeniem,
dostarczeniem
i
instalacją części systemu fizycznego. W
UML aspekty statyczne tej perspektywy
wyraża się za pomocą diagramu wdrożenia,
a dynamiczne za pomocą diagramów
interakcji, diagramów stanów i diagramów
czynności.
53
Perspektywy UML (II)
■
Pojęciowa
Reprezentuje pojęcia analizowanej dziedziny.
Pojęcia te będą
związane z klasami je implementującymi, ale często nie będzie między nimi
pełnej odpowiedniości. Model pojęciowy powinien być tworzony niezależnie od
oprogramowania, które może implementować ten model, tak aby można go było
traktować jako niezależny językowo.
■
Specyfikacyjna
Dotyczy już oprogramowania, ale raczej interfejsów niż
implementacji.
Mimo że programowanie obiektowe kładzie duży nacisk na
różnicę między interfejsem a implementacją, to w praktyce często się o tym
zapomina, bo pojęcie klasy w językach programowania obiektowego łączy
pojęcia interfejsu i implementacji. Nie powinno tak być – kluczem do
efektywnego programowania obiektowego jest programowanie sterowane
interfejsem klasy, a nie sposobem implementacji.
■
Implementacyjna
Dokładnie ukazuje całą implementację.
Jest to prawdopodobnie
najczęściej używana perspektywa, ale w wielu przypadkach lepiej przyjąć
perspektywę specyfikacyjną.
54
Rodzaje diagramów UML
■
Diagramy struktury
służą do obrazowania, specyfikowania,
tworzenia i dokumentowania statycznych
aspektów systemu
■
Diagramy zachowania
służą do obrazowania, specyfikowania,
tworzenia i dokumentowania dynamicznych
aspektów systemu
55
Rodzaje diagramów UML
■
Diagramy struktury
Diagram klas
Diagram obiektów
Diagram pakietów
Diagramy fizyczne
➔
Diagram komponentów
➔
Diagram wdrożenia
■
Diagramy zachowania
Diagram przypadków użycia
Diagramy interakcji
➔
Diagram przebiegu (sekwencji)
➔
Diagram kooperacji (współdziałania)
Diagram stanów
Diagram czynności
56
Diagram klas
Na diagramie klas mogą znaleźć się klasy,
interfejsy, kooperacje i związki między nimi.
Jest to najczęściej spotykany diagram w
modelach obiektowych. Odnosi się do
statycznych
aspektów
perspektywy
projektowej. Diagram klas uwzględniający
klasy aktywne dotyczy statycznych aspektów
perspektywy procesowej.
57
Diagram klas
■
Opisuje typy obiektów w systemie i różne
rodzaje statycznych relacji między nimi. Są
dwa główne rodzaje relacji statycznych:
asocjacje (np. klient może wypożyczyć kilka
kaset wideo)
podtypy (np. pielęgniarka jest osobą)
■
Diagram klas pokazuje również atrybuty
i operacje klas oraz ograniczenia tego, w jaki
sposób obiekty mogą być powiązane.
58
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
59
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
klasa
60
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
atrybuty
61
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
operacj
e
62
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
uogólnienie
Diagramy klas
63
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
asocjacja
Diagramy klas
64
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
Krotność:
obowiązkowe
Diagramy klas
65
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
Krotność:
wiele
66
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
Krotność:
opcjonalny
67
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
Nazwa roli
68
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
ograniczeni
e
Diagramy klas
69
Diagramy klas
Zamówienie
DataOtrzymania
przedpłata
numer: String
cena: waluta
wyślij()
zamknij()
Klient
nazwa
adres
WiarygodnośćKredytowa(): String
Klient firmowy
osobaDoKontaktów
wiarygodnośćKredytowa
limitKredytowy
przypomnij()
obciążZaMiesiąc(Integer)
Klient indywidualny
numerKartyKredytowej
Pozycja zamówienia
ilość: Integer
cena: waluta
zapewniona: Boolean
Pracownik
Towar
*
0..1
*
1
*
1
1
*
pozycje
przedstawiciel
handlowy
{wiarygodnośćKredytowa()
== „niska”}
{jeśli Zamówienie.klient.
wiarygodnośćKredytowa
jest „niska”, to Zamówienie.
przedpłata musi być
prawdziwe}
nawigowalność
70
Diagram obiektów
Element struktury
organizacyjnej
siedziba
Osoba
Organizacja
* dzieci
1 rodzic
■
Diagram obiektów jest obrazem obiektów
w systemie w określonej chwili
■
Jest bardzo przydatny, gdy możliwe
powiązania między obiektami są
skomplikowane
71
Diagram obiektów
Element struktury
organizacyjnej
siedziba
Osoba
Organizacja
* dzieci
1 rodzic
dział oprogramowania: Organizacja
siedziba = „Warszawa”
narzędzia: Organizacja
siedziba = „Poznań”
aplikacje: Organizacja
siedziba = „Paryż”
Anna: Osoba
siedziba = „Kraków”
Jan: Osoba
siedziba = „Kraków”
rodzic
rodzic
72
Operacje i atrybuty w zasięgu klasy
Zamówienie
pobierzNumer()
pobierzNastępnyNowyNumer()
zasięg
instancji
zasięg
klasy
■
UML określa operację lub atrybut, których
obszar działania to klasa, a nie instancja tej
klasy, jako będące w zasięgu klasy.
■
Jest to równoważne statycznym składowym
w C++ lub Javie
73
Klasyfikacja wielokrotna
Osoba
Kobieta
Mężczyzna
Pacjent
Lekarz
Pielęgniarz
Fizjo-
terapeuta
Chirurg
Lekarz
domowy
Pacjent
Rola
Płeć
{complete}
wyróżnik
74
Klasyfikacja dynamiczna
Osoba
Kobieta
Mężczyzna
Lekarz
Pielęgniarz
Fizjo-
terapeuta
Płeć
{complete}
Zawód
<<dynamiczna>>
75
Agregacja i zawieranie
Styl
kolor
jestWypełniony
Wielokąt
Punkt
Koło
promień
{ordered}
3..*
*
1
1
1
*
zawieranie
agregacja
76
Alternatywna notacja dla zawierania
Styl
Koło
Punkt
*
1
1
1
*
Wielokąt
Punkt
{ordered} 3..*
Koło
Punkt
1
77
Asocjacje i atrybuty pochodne
Rachunek
skrócony
Rachunek
/saldo: Waluta
komponenty
{hierarchy}
1
*
Zapis
wartość: Waluta
Rachunek
szczegółowy
Rola zapisów pochodzi
z komponenty.zapisy
/Zapisy
*
0..1
{saldo = suma wartości zapisów}
asocjacja
pochodna
atrybut
pochodny
uwaga
78
Klasy abstrakcyjne
Okno
{abstract}
Edytor
tekstów
pierwszyPlan()
ostatniPlan()
Okno w Windows
pierwszyPlan()
ostatniPlan()
Okno w X11
pierwszyPlan()
ostatniPlan()
Okno w MacIntoshu
pierwszyPlan()
ostatniPlan()
zależność
79
Klasy abstrakcyjne
<<interface>>
DataInput
CzytnikZamówień
DataInputStream
InputStream
zależność
realizacja
uogólnienie
80
Notacja „lizakowa”
CzytnikZamówień
DataInputStream
DataInput
InputStream
interfejs
zależność
81
Zbiory dla wielokrotnych stron asocjacji
■
Strona wielokrotna asocjacji to ta, której
górne ograniczenie krotności jest większe niż
1(na przykład *)
■
Zwykle strony wielokrotne traktujemy jako
zbiory (nieuporządkowane, nie powtarzają
się)
■
Inne możliwości:
{ordered}
{bag}
{hierarchy}
{dag}
82
Asocjacje kwalifikowane
Pozycja zamówienia
Towar
Ilość: Liczba
Zamówienie
0..1
Pozycja
83
Klasy asocjacyjne
Zatrudnienie
okres: zakresDat
Osoba
0..1
Pracodawca
Przedsiębiorstwo
*
84
Klasy asocjacyjne
Zatrudnienie
okres: zakresDat
Osoba
0..1
/Pracodawca
Przedsiębiorstwo
*
*
0..1
1
1
85
Klasy asocjacyjne
Zatrudnienie
okres: zakresDat
Osoba
*
Pracodawca
Przedsiębiorstwo
*
86
Klasy asocjacyjne
Kwalifikacje
poziom
Osoba
Umiejętności
*
*
87
Klasy asocjacyjne
Osoba
0..1
Pracodawca
<<history>>
Przedsiębiorstwo
*
88
Klasy parametryzowane
Zbiór
wstaw(T)
usuń(T)
T
Zbiór<Pracownik>
Zbiór
wstaw(T)
usuń(T)
T
ZbiórPracowników
<<bind>>
<Pracownik>