wykład VII Faza analizy analiza obiektowa Język UML ...Unified Modeling Language, UML). K. Bartecki, Inżynieria oprogramowania, VII/14 2009 UML 2.2 2015 UML 2.5 Historia UML „Drzewo
Post on 08-Jun-2020
32 Views
Preview:
Transcript
Inżynieria oprogramowania
wykład VII
Faza analizy – analiza obiektowa
Język UML – wprowadzenie, diagramy struktury
prowadzący: dr hab. inż. Krzysztof Bartecki, prof. PO
W niniejszym wykładzie wykorzystano m.in. materiały dydaktyczne ze
strony projektu „Opracowanie programów nauczania na odległość na
kierunku studiów wyższych – Informatyka” autorstwa p. Bartosza Waltera:
http://wazniak.mimuw.edu.pl/index.php?title=Io-5-wyk-toc
K. Bartecki, Inżynieria oprogramowania, VII/2
Faza analizy systemowej – ciąg dalszy
Przypomnienie:
Jej celem jest udzielenie odpowiedzi na pytanie: jak system ma działać?
W wyniku fazy analizy otrzymujemy logiczny model systemu, opisujący
sposób realizacji przez system postawionych wymagań, lecz abstrahujący
od szczegółów implementacyjnych.
K. Bartecki, Inżynieria oprogramowania, VII/3
Wymagania Projektowanie Implementacja Testowanie Konserwacja
Strategiczna Analiza Instalacja
Dokumentacja
K. Bartecki, Inżynieria oprogramowania, VII/4
Metody analizy systemowej – podział
STRUKTURALNE
Wyróżniają w systemie dwa
rodzaje składowych:
● pasywne (dane),
● aktywne (operacje - funkcje).
OBIEKTOWE
Opisują system jako układ
współdziałających z sobą
obiektów, łączących w jedną
całość dane i operacje na
tych danych wykonywane.
K. Bartecki, Inżynieria oprogramowania, VII/5
struct Punkt
{
int x, y;
};
void narysuj(struct Punkt P)
{
// ciało funkcji
}
class Punkt
{
int x, y;
public:
void narysuj()
{
// ciało funkcji
}
};
Podejście strukturalne (C++): Podejście obiektowe (C++):
Różnica między podejściem strukturalnym a obiektowym
K. Bartecki, Inżynieria oprogramowania, VII/6
Pojęcie obiektu oraz klasy
(przypomnienie)
Obiekt:
● to konkretny lub abstrakcyjny byt, wyróżnialny w modelowanej
rzeczywistości,
● posiada określone granice i atrybuty (właściwości),
● może świadczyć określone usługi, czyli wykonywać określone
operacje oraz przejawiać określone zachowanie.
Klasa to:
● opis takich cech grupy podobnych obiektów, które są dla nich
niezmienne – np. zestaw atrybutów i operacji (metod), czyli usług,
które mogą one świadczyć.
Analiza obiektowa
Popularność obiektowych metod analizy ściśle wiąże się
z rosnącą popularnością obiektowych języków programowania oraz
środowisk implementacji.
Programowanie obiektowe ułatwia m.in.:
● hermetyzację (ukrywanie) danych (ang. data encapsulation),
● ponowne wykorzystanie kodu (ang. code reuse),
● szybkie prototypowanie aplikacji (ang. rapid prototyping),
● programowanie oparte na zdarzeniach (ang. event-driven
programming).
K. Bartecki, Inżynieria oprogramowania, VII/7
Dzięki hermetyzacji zwiększamy odporność programu na błędy poprzez:
● ochronę przed nieświadomym „popsuciem” obiektu – użytkownik klasy
nie ma dostępu do jej prywatnych pól,
● zapewnienie właściwego interfejsu – użytkownik ma do dyspozycji
tylko niezbędne operacje, co ułatwia mu korzystanie z klasy,
● ochronę przed konsekwencjami zmiany implementacji – twórca klasy
może zmienić zestaw prywatnych atrybutów oraz implementację
prywatnych metod, nie zmieniając interfejsu publicznego – wszystkie
programy napisane przy wykorzystaniu tego interfejsu nie będą
wymagały żadnych zmian.
K. Bartecki, Inżynieria oprogramowania, VII/8
Hermetyzacja danych polega na tym, że
dane obiektu (reprezentowane przez jego
atrybuty) są ukryte („prywatne”)
i traktowane jako nierozdzielna całość
z „publicznymi” usługami (operacjami),
udostępnionymi przez obiekt.
Ponowne wykorzystanie kodu polega na wykorzystaniu już istniejących
klas przy tworzeniu nowych klas, co znacznie oszczędza pracę przy
kodowaniu, a także czyni programowanie mniej podatne na błędy.
Istnieją dwa sposoby ponownego wykorzystania kodu klas:
● kompozycja, czyli definiowanie w nowo tworzonej klasie pól
obiektowych reprezentowanych przez klasę już istniejącą, np.:
public class RegisteredUser {
private Person person;
private Address address;
private String email;
// ...
}
● dziedziczenie, czyli przejęcie właściwości i funkcjonalności obiektów
innej klasy i ewentualną ich modyfikację w taki sposób, aby były one
bardziej wyspecjalizowane (tzw. związek generalizacji-specjalizacji):
public class AppartmentAddress extends Address {
// ...
}
K. Bartecki, Inżynieria oprogramowania, VII/9
K. Bartecki, Inżynieria oprogramowania, VII/10
Szybkie prototypowanie aplikacji oraz programowanie oparte na
zdarzeniach jest obecnie możliwe głównie dzięki wykorzystaniu narzędzi
RAD (ang. Rapid Application Development), czyli narzędzi do szybkiego
wytwarzania aplikacji.
● Narzędzia RAD wywodzą się z klasycznych zintegrowanych środowisk
programistycznych (ang. Integrated Development Environment, IDE)
i oparte są na bibliotekach obiektowych, pozwalających łatwo
tworzyć graficzny interfejs użytkownika (ang. Graphical User Interface,
GUI), a także umożliwiają dostęp do baz danych.
● Pierwszym popularnym środowiskiem o cechach RAD był Visual Basic
firmy Microsoft (koniec lat 80. XX wieku, oficjalna premiera w 1991).
● Przykłady popularnych narzędzi RAD:
o C++Builder (Borland, od 2009 Embarcadero Technologies),
o Delphi (Borland, od 2009 Embarcadero Technologies),
o Visual Studio (Microsoft),
o NetBeans (Sun Microsystems, od 2010 Oracle Corporation),
o Lazarus (projekt open source, oparty na kompilatorze Free
Pascal, zgodny z Delphi).
K. Bartecki, Inżynieria oprogramowania, VII/11
Wygląd pierwszej wersji narzędzia Visual Basic z roku 1991
Analiza obiektowa – c.d.
Na początku lat 90. ubiegłego wieku istniało wiele notacji i metodyk analizy
obiektowej, stosujących elementy o zbliżonej semantyce (np. pojęcie klasy),
ale różniące się sposobem ich reprezentacji.
Należały do nich m.in.:
● OMT (ang. Object Modelling Technique), J. Rumbaugh, 1991;
● OOSE (ang. Object-Oriented Software Engineering), I. Jacobson, 1992;
● OOAD (ang. Object-Oriented Analysis and Design), G. Booch, 1994;
● OOA, OOD (ang. Object-Oriented Analysis, Object-Oriented Design),
P. Coad i E. Yourdon, 1994.
K. Bartecki, Inżynieria oprogramowania, VII/12
K. Bartecki, Inżynieria oprogramowania, VII/13
Około roku 1995 Booch, Jacobson i Rumbaugh („trzej amigos”) podjęli
działania nad ujednoliceniem swoich notacji, tworząc jedną metodę – tak
powstała najpierw Metoda Zunifikowana (ang. Unified Method), a następnie
Zunifikowany Język Modelowania (ang. Unified Modeling Language, UML).
UML zawiera dwie podstawowe składowe:
● notację poszczególnych elementów używanych na diagramach,
● metamodel, czyli definicje pojęć języka i powiązania między nimi.
Z punktu widzenia analityka istotniejsze jest czytelne i jednoznaczne
opisanie modelu tak, aby inne osoby mogły zrozumieć jego znaczenie.
Zatem ważniejsza dla niego jest notacja, zaś metamodel powinien być
zrozumiały intuicyjnie.
Z kolei przy generowaniu kodu i przejściu do implementacji, ważniejsze
jest ścisłe rozumienie znaczenia poszczególnych elementów – czyli
metamodel.
Uwaga:
● UML nie jest metodyką obiektową – nie określa metody modelowania.
● UML jest językiem modelowania obiektowego.
K. Bartecki, Inżynieria oprogramowania, VII/16
W najnowszej wersji UML (2.5) wyróżnia się 14 rodzajów diagramów,
podzielonych na dwie główne grupy:
● diagramy opisujące strukturę systemu (ang. structure diagrams),
● diagramy opisujące zachowanie systemu (ang. behavior diagrams).
K. Bartecki, Inżynieria oprogramowania, VII/17
Diagramy struktury:
● diagram klas (ang. class diagram),
● diagram obiektów (ang. object diagram),
● diagram komponentów (ang. component diagram),
● diagram wdrożeniowy (ang. deployment diagram),
● diagram pakietów (ang. package diagram) – od UML 2.0,
● diagram struktur złożonych (ang. composite structure diagram) – od
UML 2.0,
● diagram profili (ang. profile diagram) – od UML 2.2.
K. Bartecki, Inżynieria oprogramowania, VII/18
Diagramy dynamiki:
● diagram przypadków użycia (ang. use case diagram),
● diagram czynności (ang. activity diagram),
● diagram maszyny stanowej (ang. state machine diagram) – wcześniej
nazywany diagramem stanów.
W ramach diagramów dynamiki wyróżnia się tzw. diagramy interakcji:
● diagram sekwencji (ang. sequence diagram),
● diagram komunikacji (ang. communication diagram) – wcześniej
nazywany diagramem współpracy lub współdziałania,
● diagram zależności czasowych (ang. timing diagram) – od UML 2.0,
● diagram przeglądu interakcji (ang. interaction overview diagram) – od
UML 2.0.
K. Bartecki, Inżynieria oprogramowania, VII/19
W praktyce rzadko wymagane jest opracowywanie wszystkich diagramów.
Najczęściej wykorzystywane diagramy:
● klas,
● przypadków użycia,
● sekwencji,
● aktywności.
Pozostałe często bywają pomijane, zwłaszcza przy projektowaniu
niewielkich systemów informatycznych.
K. Bartecki, Inżynieria oprogramowania, VII/20
W ramach diagramów struktury UML na wykładzie omówione zostaną:
● diagram klas,
● diagram obiektów,
● diagram pakietów,
● diagram komponentów,
● diagram wdrożeniowy.
K. Bartecki, Inżynieria oprogramowania, VII/22
Diagram klas
● jest podstawowym diagramem przedstawiającym logiczną strukturę
systemu,
● przedstawia występujące w systemie klasy i zachodzące pomiędzy nimi
statyczne relacje,
● klasy na diagramie reprezentowane przez prostokąty – mogą one
zawierać, oprócz nazwy klasy, informację o jej danych składowych
(atrybutach) i operacjach dostarczanych przez klasę (metodach),
● spośród wszystkich diagramów UML jest on najbardziej „pojemny”
i z tego względu jest najczęściej stosowany do generowania kodu na
podstawie modelu.
K. Bartecki, Inżynieria oprogramowania, VII/23
Tworzenie diagramu klas obejmuje:
● identyfikację klas,
● identyfikację związków pomiędzy klasami,
● identyfikację i definiowanie pól danych (atrybutów),
● identyfikację i definiowanie operacji (metod) i komunikatów.
Kolejność wykonywania tych czynności nie jest ściśle ustalona i zależy
zarówno od stylu pracy, jak i od konkretnego problemu.
K. Bartecki, Inżynieria oprogramowania, VII/24
Klasa jest reprezentowana na diagramie przez prostokąt z wydzielonymi
przedziałami: nazwą, atrybutami i operacjami.
K. Bartecki, Inżynieria oprogramowania, VII/26
nazwa
atrybuty
operacje
Cechy klasy
● reprezentują informację, jaką klasa przechowuje,
● mogą zostać zapisane w postaci dwóch równoważnych notacji:
o jako atrybuty klasy (umieszczane w przedziale atrybutów),
o jako związki pomiędzy klasami (zapisywane w postaci linii łączącej
klasy).
● pierwsza notacja jest zwykle stosowana do typów prostych, natomiast
druga – do typów złożonych (klas).
● na przykład, na naszym diagramie nr zamówienia, który jest typu
prostego (long int) został zapisany jako atrybut klasy Zamówienie, zaś
Klient został uwzględniony poprzez związek łączący te dwie klasy.
K. Bartecki, Inżynieria oprogramowania, VII/27
1..1
skladajacy
0..*
skladane
Klient
-
-
-
-
nazwisko_imie
adres
telefon
: std::string
: std::string
: std::string
: std::string
+
+
Klient (std::string ni, std::string ad, std::string em, std::string te)
~Klient ()
Zamówienie
-
-
-
-
nr zamówienia
kwota zamówienia
data zamówienia
czy opłacone
: long
: float
: std::string
: bool
+
+
Zamowienie (long nr)
~Zamowienie ()
...
Atrybut
zwykle jest opisywany tylko przez dwa elementy: nazwę i typ.
Jednak pełna jego definicja może obejmować także dodatkowe informacje:
K. Bartecki, Inżynieria oprogramowania, VII/28
K. Bartecki, Inżynieria oprogramowania, VII/30
Operacje klasy
● reprezentują usługi, jakie klasa oferuje,
● realizacje operacji – czyli metody – dostarczają implementacji tych
usług,
● oprócz nazwy operacji wraz listą jej parametrów oraz informacją o
zwracanym przez nią typie, jej definicja na diagramie może obejmować
pewne dodatkowe informacje:
Związki klas
to ogólne określenie relacji zachodzących między klasami, gdy jedna
z nich w pewien sposób „używa” innej klasy.
Diagramy klas mogą uwzględniać następujące rodzaje związków:
● zależność (ang. dependency),
● asocjacja (ang. association),
● agregacja (ang. aggregation),
● kompozycja (ang. composition),
● generalizacja-specjalizacja (ang. generalization-specialization).
K. Bartecki, Inżynieria oprogramowania, VII/31
Właściwości związku zależności
● Zależność pomiędzy klasami A i B informuje, że jedna z nich, aby
używać obiektów innej, musi mieć o niej informacje.
● Zależność występuje, gdy zmiana specyfikacji klasy A, może
powodować konieczność wprowadzania zmiany w klasie B.
● Najczęściej używa się zależności do pokazania, że klasa A używa
klasy B jako parametru jakiejś operacji, lub że operacje klasy A
tworzą lokalne obiekty klasy B.
● Obie klasy są zależne od siebie nawzajem w celu zapewnienia
poprawnego działania systemu.
● Zależności często opisuje się frazami: „korzysta z”, „oddziałuje na”, „ma
wpływ na”, „tworzy”.
K. Bartecki, Inżynieria oprogramowania, VII/33
Przykład implementacji związku zależności w kodzie Javy
import B;
public class A
{
public void method1(B b) // obiekt klasy B jako parametr
{ // . . . } // metody klasy A
public void method2()
{ B tempB = new B() } // metoda klasy A tworzy
} // lokalny obiekt klasy B
K. Bartecki, Inżynieria oprogramowania, VII/34
K. Bartecki, Inżynieria oprogramowania, VII/35
Związek asocjacji
1..1
skladajacy
0..*
skladane
Klient
-
-
-
-
nazwisko_imie
adres
telefon
: std::string
: std::string
: std::string
: std::string
+
+
Klient (std::string ni, std::string ad, std::string em, std::string te)
~Klient ()
Zamówienie
-
-
-
-
nr zamówienia
kwota zamówienia
data zamówienia
czy opłacone
: long
: float
: std::string
: bool
+
+
Zamowienie (long nr)
~Zamowienie ()
...
Właściwości związku asocjacji
● Asocjacje są relacjami silniejszymi niż zależności – wskazują, że jeden
obiekt jest związany z innym przez pewien okres czasu, jednak czas
życia obu obiektów nie jest od siebie zależny: usunięcie jednego nie
powoduje usunięcia drugiego.
● W przypadku asocjacji żaden obiekt nie jest właścicielem drugiego: nie
tworzy go, nie zarządza nim, a moment usunięcia drugiego obiektu nie
jest z nim związany.
● Asocjacje mogą posiadać nazwy, zwykle w formie czasownika,
pozwalającego przeczytać w języku naturalnym jej znaczenie, np.
„A posiada B”.
K. Bartecki, Inżynieria oprogramowania, VII/36
Właściwości związku asocjacji – c.d.
● Najczęściej używa się związku asocjacji do pokazania, że obiekt klasy A
może zawierać (lub być związany z) jednym lub wieloma obiektami klasy
B.
● Asocjacja jest równoważna atrybutowi i reprezentuje cechę klasy.
● Przyjmuje się konwencję, w której cechy reprezentujące typy proste
(liczby, napisy, znaki) są modelowane jako atrybuty, natomiast
obiekty dostępne poprzez referencje – są przedstawiane poprzez
asocjacje.
K. Bartecki, Inżynieria oprogramowania, VII/37
Krotność danego końca asocjacji to dopuszczalna liczba obiektów klasy
znajdującej się przy tym końcu, skojarzonych z jednym obiektem klasy na
drugim końcu tej asocjacji.
Krotności są pojedynczymi liczbami albo zakresami liczb:
Krotność Znaczenie
0..1 Brak obiektu lub jeden obiekt.
0..* Bez ograniczenia liczby obiektów
(łącznie z ich brakiem).
1 Dokładnie jeden obiekt.
1..* Przynajmniej jeden obiekt.
n Dokładnie n obiektów.
m .. n Od m do n obiektów.
K. Bartecki, Inżynieria oprogramowania, VII/38
Przykład implementacji związku asocjacji w kodzie Javy
import B;
public class A {
private B b; // obiekt klasy B jako składowa
public B getB() { // (cecha) klasy A
return b;
}
}
K. Bartecki, Inżynieria oprogramowania, VII/40
A B
Nawigowalność – asocjacje skierowane
● Nawigowalność pomiędzy klasą A i klasą B oznacza, że od obiektu
klasy A można przejść do obiektu klasy B, ale nie odwrotnie
● Innymi słowy: obiekty klasy A posiadają odwołanie do obiektu (lub
obiektów) klasy B, ale nie odwrotnie.
● Nawigowalność oznaczana jest na diagramach strzałką skierowaną od
klasy A do klasy B.
● Nawigowalność (asocjacja) dwukierunkowa oznacza, że nawigując od
obiektu klasy A do obiektu klasy B, a następnie z powrotem, w zbiorze
wyników można znaleźć początkowy obiekt klasy A.
● Innymi słowy: zarówno obiekty klasy A posiadają odwołanie do obiektu
(lub obiektów) klasy B, jak i obiekty klasy B posiadają odwołanie do
obiektu (lub obiektów) klasy A.
● W przypadku nawigowalności dwukierunkowej strzałki pomija się (tak
było do UML 2.4).
K. Bartecki, Inżynieria oprogramowania, VII/41
K. Bartecki, Inżynieria oprogramowania, VII/42
Notacja nawigowalności obowiązująca od UML w wersji 2.4
nieokreślona nawigowalność między A1 a B1 oraz B1 a A1
nawigowalność między A2 a B2 oraz nieokreślona
nawigowalność między B2 a A2
brak nawigowalności między B3 a A3 oraz nieokreślona
nawigowalność między A3 a B3
nawigowalność między A4 a B4 oraz brak nawigowalności
między B4 a A4
obustronna nawigowalność między A5 a B5
obustronny brak nawigowalności między A6 a B6
Przykład implementacji asocjacji skierowanej w kodzie języka C++
class Klient
{
public:
// …
private:
int nrklienta;
std::string nazwisko;
};
class Zamowienie
{
public:
// …
private:
Klient* klient;
int nr_zamowienia;
float kwota_zamowienia;
};
K. Bartecki, Inżynieria oprogramowania, VII/43
składanie1..1
0..*
Klient
-
-
nr klienta
nazwisko
: int
: std::string
Zamówienie
-
-
nr zamówienia
kwota zamówienia
: int
: float
class Klient
{
public:
//…
private:
std::list<Zamowienie> zamowienia;
int nr_klienta;
std::string nazwisko;
};
class Zamowienie
{
public:
//…
private:
int nr_zamowienia;
float kwota_zamowienia;
};
K. Bartecki, Inżynieria oprogramowania, VII/44
składanie1..1
0..*
Klient
-
-
nr klienta
nazwisko
: int
: std::string
Zamówienie
-
-
nr zamówienia
Kwota zamówienia
: int
: float
Przykład implementacji asocjacji skierowanej w kodzie języka C++
class Klient
{
public:
//…
private:
std::list<Zamowienie> zamowienie;
int nr_klienta;
std::string nazwisko;
};
class Zamowienie
{
public:
//…
private:
Klient* klient;
int nr_zamowienia;
float kwota_zamowienia;
};
Przykładowa implementacja asocjacji dwukierunkowej w C++
K. Bartecki, Inżynieria oprogramowania, VII/45
składanie1..1
0..*
Klient
-
-
nr klienta
nazwisko
: int
: std::string
Zamówienie
-
-
nr zamówienia
Kwota zamówienia
: int
: float
K. Bartecki, Inżynieria oprogramowania, VII/46
Klasa asocjacyjna
1..*
przedmiotem
0..*
dotyczy
Tytuł
-
-
tekst tytułu
cena tytułu
: std::string
: float
+
+
+
+
<<Constructor>>
<<Destructor>>
Tytul (std::string t, float c)
~Tytul ()
zwróć tekst ()
zwróć cenę ()
: std::string
: float
Zamówienie
-
-
-
-
nr zamówienia
kwota zamówienia
data zamówienia
czy opłacone
: long
: float
: std::string
: bool
+
+
<<Constructor>>
<<Destructor>>
Zamowienie (long nr)
~Zamowienie ()
...
Pozycja
-
-
nr pozycji
l iczba sztuk
: short
: short
klasa asocjacyjna
Klasa asocjacyjna – właściwości
● Klasa asocjacyjna umożliwia opisanie za pomocą atrybutów i operacji
nie obiektu, ale samej asocjacji pomiędzy klasami.
● Informacje przechowywane w klasie asocjacyjnej nie są związane
z żadną z klas uczestniczących w asocjacji, dlatego wygodnie jest
stworzyć dodatkową klasę i powiązać ją z relacją asocjacji.
● Klasa asocjacyjna na etapie modelowania logicznego może zostać
przekształcona do postaci „zwykłej” (nieasocjacyjnej) klasy.
K. Bartecki, Inżynieria oprogramowania, VII/47
Zamiana klasy asocjacyjnej
w „zwykłą” klasę na diagramie implementacyjnym
K. Bartecki, Inżynieria oprogramowania, VII/48
Asocjacja kwalifikowana – właściwości
● Asocjacja kwalifikowana jest rozszerzeniem zwykłej asocjacji
o możliwość określenia, który z atrybutów jednej z klas decyduje
o związku między tymi klasami.
● Na przykład, jeden Klient może złożyć wiele różnych Zamówień.
● Jednak dany Klient może złożyć tylko jedno Zamówienie o danym
numerze – dlatego atrybut nr_zamówienia klasy Zamówienie jest
kwalifikatorem tej asocjacji.
● W efekcie pomiędzy pojedynczym obiektem klasy Klient a
pojedynczym obiektem klasy Zamówienie występuje asocjacja o
liczebności „jeden do jednego”.
K. Bartecki, Inżynieria oprogramowania, VII/50
K. Bartecki, Inżynieria oprogramowania, VII/51
Związek agregacji
0..*
zawiera
0..*
zawarty
Tytuł
-
-
tekst tytułu
cena tytułu
: std::string
: float
+
+
+
+
<<Constructor>>
<<Destructor>>
Tytul (std::string t, float c)
~Tytul ()
zwróć tekst ()
zwróć cenę ()
: std::string
: float
Katalog tytułów
- l iczba tytułów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Katalog_tytulow ()
~Katalog_tytulow ()
dodaj tytuł (Tytul t)
usuń tytuł (Tytul t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Agregacja – właściwości
● Agregacja jest silniejszą formą asocjacji,
● agregacja to związek, w którym jedna z klas należy do kolekcji,
której właścicielem jest obiekt innej klasy (np. Klasa może stanowić
agregację Uczniów),
● w przypadku agregacji istnieje właściciel i obiekt podrzędny (obiekty
podrzędne),
● właściciel jednak nie jest wyłącznym właścicielem obiektu
podrzędnego (dany obiekt podrzędny może mieć wielu różnych
właścicieli), zwykle też nie tworzy i nie usuwa go,
● w konsekwencji, właściciel i obiekt podrzędny nie są ze sobą
powiązane czasem swojego życia,
● związek agregacji na diagramie zaznacza się białym rombem po
stronie klasy reprezentującej właściciela.
K. Bartecki, Inżynieria oprogramowania, VII/52
K. Bartecki, Inżynieria oprogramowania, VII/53
Związek kompozycji
1..1
składa się z
1..*
wchodzi w skład
Książka
-
-
tytuł
autor
: String
: String
Tom
-
-
numer
liczba stron
: int
: int
Kompozycja – właściwości
● Kompozycja jest najsilniejszą relacją łączącą klasy,
● reprezentuje relacje całość-część, w których części są tworzone
i zarządzane przez obiekt reprezentujący całość,
● ani całość, ani części nie mogą istnieć bez siebie, dlatego czasy ich
istnienia są bardzo ściśle ze sobą związane i pokrywają się,
● w momencie usunięcia obiektu reprezentującego całość, obiekty
reprezentujące części są również usuwane,
● związek kompozycji na diagramie zaznacza się zaczernionym
rombem po stronie klasy reprezentującej całość.
K. Bartecki, Inżynieria oprogramowania, VII/54
Agregacja i kompozycja – przykłady implementacji w C++
class Department
{
private:
std::string depName;
University* univ;
Professor* members[20];
...
};
class University
{
private:
std:string univName
Department faculty[10];
create_dept()
{
// Composition
faculty[0]=Department(..);
faculty[1]=Department(..);
...
}
};
class Professor
{
private:
std::string profName;
Department*
affiliation[];
...
};
K. Bartecki, Inżynieria oprogramowania, VII/55
1..10 1..20
K. Bartecki, Inżynieria oprogramowania, VII/56
Związek generalizacji-specjalizacji (uogólnienia-uszczegółowienia)
Tytuł
-
-
tekst tytułu
cena tytułu
: std::string
: float
+
+
+
+
<<Constructor>>
<<Destructor>>
Tytul (std::string t, float c)
~Tytul ()
zwróć tekst ()
zwróć cenę ()
: std::string
: float
Książka
-
-
autor
liczba stron
: std::string
: short
Czasopismo
- częstotliwość : bool
generalizacja
specjalizacje
Uogólnienie (generalizacja-specjalizacja) – właściwości
● Jest to związek występujący między klasą bardziej ogólną (nadklasą,
rodzicem, generalizacją) a klasą bardziej szczegółową (podklasą,
dzieckiem, specjalizacją),
● podklasa jest w pełni zgodna z klasą nadrzędną (posiada wszystkie jej
cechy i operacje) i ponadto zawiera dodatkowe cechy i/lub operacje,
● uogólnienie często jest traktowane jako synonim dziedziczenia.
K. Bartecki, Inżynieria oprogramowania, VII/57
Przykład złożonej hierarchii generalizacji-specjalizacji
K. Bartecki, Inżynieria oprogramowania, VII/58
Generalizacja-specjalizacja – implementacja w kodzie Javy, C++ i C#
K. Bartecki, Inżynieria oprogramowania, VII/59
public class B2
{
//…
}
public class A2 extends B2
{
//…
}
class B2
{
//…
};
class A2 : public B2
{
//…
};
class B2
{
//…
}
class A2 : B2
{
//…
}
Java C++
C#
Klasa abstrakcyjna
● Klasa abstrakcyjna jest pewnym uogólnieniem (generalizacją) innych
klas, lecz nie posiada swoich instancji, czyli obiektów.
● Celem tworzenia klas abstrakcyjnych i interfejsów jest identyfikacja
wspólnych zachowań różnych klas, które są realizowane w różny od
siebie sposób.
● Posiada ona deklaracje metod, ale nie definiuje ich implementacji.
● Metody te implementowane są w jej klasach pochodnych –
specjalizacjach.
K. Bartecki, Inżynieria oprogramowania, VII/60
Przykład definicji klasy abstrakcyjnej w kodzie języka C++
class Abstrakcyjna
{
public:
virtual void metoda () = 0; // metoda czysto wirtualna
};
class Nieabstrakcyjna : public Abstrakcyjna // dziedziczenie
{
public:
void metoda () // implementacja metody czysto wirtualnej
{
// instrukcje metody
}
};
int main()
{
// Abstrakcyjna obiektX; // błąd, klasa jest abstrakcyjna
Nieabstrakcyjna obiektY; // poprawne
return 0;
}
K. Bartecki, Inżynieria oprogramowania, VII/62
Przykład definicji klasy abstrakcyjnej w kodzie języka Java
abstract class Figura {
abstract public double pole();
}
class Kolo extends Figura { // dziedziczenie
public double promien;
public Kolo( double p ) {
this.promien = p;
}
public double pole() { // implementacja metody czysto wirtualnej
return 3.14 * promien * promien;
}
}
public class Program {
public static void main( String[] args ) {
// Figura f = new Figura(); // niemożliwe: Figura jest klasą abstrakcyjną
Kolo k = new Kolo( 2 );
System.out.println( k.pole() );
}
}
K. Bartecki, Inżynieria oprogramowania, VII/63
Interfejs
jest pojęciem bardzo podobnym do klasy abstrakcyjnej. Deklaruje on
zestaw operacji, które określają usługi oferowane przez klasę, bez
podawania ich implementacji.
K. Bartecki, Inżynieria oprogramowania, VII/64
<<implementuje>> <<implementuje>>Katalog tytułów
- l iczba tytułów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Katalog_tytulow ()
~Katalog_tytulow ()
dodaj tytuł (Tytul t)
usuń tytuł (Tytul t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Lista klientów
- l iczba klientów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Lista_klientow ()
~Lista_klientow ()
dodaj klienta (Klient t)
usuń klienta (Klient t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Sortowalna
+ sortuj ()
...
: bool
interfejs
klasy dziedziczące (implementujące) interfejs
K. Bartecki, Inżynieria oprogramowania, VII/65
Zasadnicze różnice między interfejsem a klasą abstrakcyjną:
● Klasa abstrakcyjna może posiadać implementacje niektórych operacji,
natomiast interfejs jest czysto abstrakcyjny i zawiera tylko deklaracje
swoich operacji.
● Klasa dziedzicząca po klasie abstrakcyjnej może (ale nie musi)
implementować wszystkie operacje, natomiast w przypadku
dziedziczenia po interfejsie wszystkie „przejęte” po nim operacje muszą
zostać zdefiniowane w klasie pochodnej.
● O ile klasy potomne tej samej klasy abstrakcyjnej są pod względem
logicznym zwykle od siebie zależne, o tyle klasy dziedziczące po
interfejsie nie muszą być z sobą logicznie związane.
● W języku C++ interfejs może być zdefiniowany jako klasa abstrakcyjna,
zaś w Javie, C#, Object Pascalu oraz PHP stosuje się w tym celu
specjalną deklarację ze słowem interface.
Alternatywna („lizakowa”) notacja interfejsu
K. Bartecki, Inżynieria oprogramowania, VII/66
Interfejs można na diagramie przedstawić także w postaci uproszczonej –
wówczas ma on postać kuli i nie widać na nim żadnych operacji.
Sortowalna
+ sortuj ()
...
: bool Sortowalna
W przypadku, gdy interfejs ma na diagramie postać kuli, związek realizacji
pomiędzy klasą a interfejsem przedstawia się za pomocą linii ciągłej.
Lista klientów
- l iczba klientów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Lista_klientow ()
~Lista_klientow ()
dodaj klienta (Klient t)
usuń klienta (Klient t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Sortowalna
<<implement>>
Lista klientów
- l iczba klientów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Lista_klientow ()
~Lista_klientow ()
dodaj klienta (Klient t)
usuń klienta (Klient t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Sortowalna
+ sortuj ()
...
: bool
W powyższym przypadku mówimy, że interfejs Sortowalna jest dostarczany
(ang. provided) lub implementowany przez klasę Lista klientów.
Alternatywna („lizakowa”) notacja interfejsu – c.d.
K. Bartecki, Inżynieria oprogramowania, VII/67
Jeśli pewna klasa korzysta z (wymaga) usług innych klas za
pośrednictwem interfejsu, wówczas mówimy o interfejsie wymaganym
(ang. required). Interfejs taki ma na diagramie symbol łuku.
<<implement>>
<<require>>
Lista klientów
- l iczba klientów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Lista_klientow ()
~Lista_klientow ()
dodaj klienta (Klient t)
usuń klienta (Klient t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Sortowalna
+ sortuj ()
...
: bool
Sortownia
Lista klientów
- l iczba klientów : int
+
+
+
+
+
+
<<Constructor>>
<<Destructor>>
<<Implement>>
Lista_klientow ()
~Lista_klientow ()
dodaj klienta (Klient t)
usuń klienta (Klient t)
sortuj ()
zwróć liczbę ()
...
: bool
: bool
: bool
: int
Sortowalna
Sortownia
interfejs dostarczany interfejs wymagany
Przykład implementacji interfejsu w kodzie języka PHP
interface Sendable {
public function getTo();
}
class Phone implements Sendable {
public function getTo() { return '609123456' ; }
}
class Email implements Sendable {
public function getTo() { return 'address@example.com'; }
}
class Sender {
public function sendTo(Sendable $obj)
{ // operacje }
}
$p = new Phone();
$e = new Email();
$s = new Sender();
$s->sendTo($p);
$s->sendTo($e);
K. Bartecki, Inżynieria oprogramowania, VII/68
Sendable
Sender
+ sendTo (Sendable obj)
Phone
+ <<Implement>> getTo ()
+ <<Implement>> getTo () : int
Diagram obiektów
● prezentuje możliwą konfigurację obiektów w określonym momencie,
● jest instancją diagramu klas, w której zamiast klas przedstawiono ich
instancje, czyli obiekty,
● jest wizualizacją hipotetycznego stanu systemu podczas jego działania,
● służy do tworzenia przykładów, pomagających zrozumieć diagram klas
oraz występujących w nim powiązań,
● używa notacji zapożyczonej z diagramów klas, chociaż większość
z nich używa wyłącznie oznaczeń obiektów i asocjacji.
K. Bartecki, Inżynieria oprogramowania, VII/70
składanie1..1
0..*
Klient
-
-
nr klienta
nazwisko
: int
: std::string
Zamówienie
-
-
nr zamówienia
Kwota zamówienia
: int
: float
K1:Klient
nr klienta
nazwisko
= 1
= Kowalski
K2:Klient
nr klienta
nazwisko
= 2
= Nowak
Z1:Zamówienie
nr zamówienia
Kwota zamówienia
= 1
= 120.00
Z2:Zamówienie
nr zamówienia
Kwota zamówienia
= 2
= 175.00
Z3:Zamówienie
nr zamówienia
Kwota zamówienia
= 3
= 224.50
Diagram klas …
… i przykładowy diagram obiektów
K. Bartecki, Inżynieria oprogramowania, VII/71
Diagram pakietów (źródło: http://brasil.cel.agh.edu.pl/~09sbfraczek/)
● W miarę wzrostu wielkości modelowanego systemu, rośnie liczba
wykorzystywanych elementów (klas, interfejsów, komponentów, itp.)
● W celu zachowania czytelności diagramów, podobne znaczeniowo
elementy (np. klasy) można grupować w formie tzw. pakietów.
● Pakiet jest przedstawiany w postaci dużego prostokąta z małym
prostokątem u góry, zwanym etykietą.
● Wewnątrz symbolu pakietu mogą być widoczne jego składniki, wraz ze
specyfikacją ich widoczności poza pakietem (publiczna lub prywatna).
● W skład pakietu mogą wchodzić inne pakiety.
K. Bartecki, Inżynieria oprogramowania, VII/74
● Na diagramie mogą występować zależności między pakietami,
wynikające z relacji między ich elementami składowymi.
● Dzięki zależnościom uwidaczniany jest jedynie fakt występowania
relacji między elementami pakietów, a nie ich szczegółowy rodzaj, np.
nie pokazujemy tu asocjacji między dwiema klasami umieszczonymi w
dwóch różnych pakietach.
● Zależności przedstawiane są na diagramie w postaci strzałek z
przerywaną linią i mogą być opatrywane następującymi stereotypami:
«import», «access» lub «merge».
● Zależność «import» między pakietem A oraz pakietem B (z grotem
skierowanym w stronę A) oznacza, że do przestrzeni nazw pakietu A
dodawane są nazwy wszystkich elementów pakietu B.
● Zależność «import» jest przechodnia: jeśli A importuje B oraz B
importuje C, to oznacza że A importuje również (pośrednio) C.
K. Bartecki, Inżynieria oprogramowania, VII/75
<<import>><<import>>
A B C
● Zależność «access» działa podobnie jak «import», ale jest
nieprzechodnia.
K. Bartecki, Inżynieria oprogramowania, VII/76
Przykład:
● w celu użycia w pakiecie Program typu Integer, należy użyć pełnej
nazwy kwalifikowanej, tzn. Types::Integer, gdyż ta składowa pakietu
Types jest publiczna, ale nie jest importowana przez pakiet Program,
● w celu użycia w pakiecie Program typu Time można używać jego
nazwy bez kwalifikatora wskazującego na pakiet Types,
● podobnie jest z użyciem w pakiecie Program typu String, jednak nie
będzie on widoczny z zewnątrz jako składowa pakietu Program oraz
nie będzie mógł być dalej z niego importowany.
+
+
+
● W przypadku zależności typu «merge» zawartość jednego pakietu (B)
jest rozszerzana o zawartość innego pakietu (A).
K. Bartecki, Inżynieria oprogramowania, VII/77
● Jest to operacja zbliżona do związku generalizacji-specjalizacji – w
jej wyniku otrzymujemy nowy pakiet (resulting package), zawierający
wszystkie składowe pakietów: rozszerzanego (receiving package)
i rozszerzającego (merged package).
Uwaga:
to nie jest UML
Przykładowy diagram pakietów
(brak oznaczenia zależności domyślnie oznacza «import»)
K. Bartecki, Inżynieria oprogramowania, VII/79
Przykładowy diagram pakietów zawierających przypadki użycia
K. Bartecki, Inżynieria oprogramowania, VII/82
Diagram komponentów (żródło: http://brasil.cel.agh.edu.pl/~09sbfraczek/)
● Komponent to wymienialny, wykonywalny fragment systemu,
z ukrytymi (hermetyzowanymi) szczegółami implementacyjnymi (np.
biblioteka .dll, podprogram).
● Komponent udostępnia zestaw interfejsów (interfejsy dostarczane),
może też wymagać pewnych interfejsów do funkcjonowania (interfejsy
wymagane).
● Komponenty służą do ponownego wykorzystania poprzez połączenie
ich z innymi komponentami, zwykle poprzez ich odpowiednie
skonfigurowanie, bez potrzeby rekompilacji.
● Diagram komponentów służy do pokazania związków pomiędzy
komponentami i interfejsami.
K. Bartecki, Inżynieria oprogramowania, VII/83
Rodzaje komponentów w UML
● executable – komponent wykonywalny,
● library – biblioteka statyczna lub dynamiczna,
● table – tabela bazy danych,
● file – dokument zawierający kod źródłowy lub dane,
● document – dokument.
K. Bartecki, Inżynieria oprogramowania, VII/84
Typy interfejsów w komponentach
● provided – interfejs dostarczany,
● required – interfejs wymagany.
K. Bartecki, Inżynieria oprogramowania, VII/85
Zależności między komponentami
● Komponenty są powiązane relacją zależności z innymi
komponentami, ponieważ wymagają ich do realizacji własnej
funkcjonalności.
● Zależność między komponentami A i B oznacza, że A korzysta z
B i zmiana w B może spowodować konieczność zmiany w A.
● Duża liczba powiązań pomiędzy komponentami, a w szczególności
zależności cykliczne, utrudniają wyznaczanie obszarów zmienności i
ich hermetyzację, a co za tym idzie – podnoszą koszt pielęgnacji
oprogramowania.
● System o dobrze zdefiniowanych interfejsach komponentów pozwala
na ich wymianę bez potrzeby modyfikacji pozostałej części systemu.
K. Bartecki, Inżynieria oprogramowania, VII/86
Widoki komponentów
● widok czarnej skrzynki – nie pokazuje szczegółów wewnętrznych,
● widok białej skrzynki – pokazuje składowe komponentu.
K. Bartecki, Inżynieria oprogramowania, VII/89
Porty
pozwalają łączyć interfejsy wewnętrzne z odpowiedzialnymi za nie
fragmentami wewnętrznymi komponentu.
K. Bartecki, Inżynieria oprogramowania, VII/90
Diagram wdrożeniowy (źródło: http://brasil.cel.agh.edu.pl/~09sbfraczek/)
● Odzwierciedla fizyczną strukturę całego systemu informatycznego,
z uwzględnieniem oprogramowania i sprzętu.
● Jednostki oprogramowania są reprezentowane przez artefakty, czyli
programy wykonywalne, biblioteki, pliki źródłowe, dane oraz archiwa.
● Stronę sprzętową reprezentują węzły, czyli poszczególne urządzenia
obliczeniowe, komunikacyjne i przechowujące, powiązane ścieżkami
komunikacyjnymi (np. połączeniem TCP/IP).
● Diagramy wdrożeniowe mogą być powiązane z diagramami
komponentów.
● Diagramy wdrożeniowe istotną rolę odgrywają przy wdrażaniu
dużych, rozproszonych systemów.
K. Bartecki, Inżynieria oprogramowania, VII/93
Przykłady graficznej notacji artefaktów
Przykłady graficznej notacji węzłów
K. Bartecki, Inżynieria oprogramowania, VII/94
top related