98
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

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

  • Upload
    others

  • View
    39

  • Download
    0

Embed Size (px)

Citation preview

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).

K. Bartecki, Inżynieria oprogramowania, VII/14

2009

UML 2.2

2015

UML 2.5

Historia UML

„Drzewo genealogiczne” UML

K. Bartecki, Inżynieria oprogramowania, VII/15

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

Przykładowe diagramy języka UML

K. Bartecki, Inżynieria oprogramowania, VII/21

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

Przykładowy diagram klas

K. Bartecki, Inżynieria oprogramowania, VII/25

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

email

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/29

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

K. Bartecki, Inżynieria oprogramowania, VII/32

Związek zależności

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

email

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łady krotności asocjacji

K. Bartecki, Inżynieria oprogramowania, VII/39

1

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

K. Bartecki, Inżynieria oprogramowania, VII/49

Asocjacja kwalifikowana

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ładowe klasy abstrakcyjne

K. Bartecki, Inżynieria oprogramowania, VII/61

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 '[email protected]'; }

}

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 ()

Email

+ <<Implement>> getTo () : int

Przykładowy diagram klas

K. Bartecki, Inżynieria oprogramowania, VII/69

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 klas …

… i przykładowy diagram obiektów

K. Bartecki, Inżynieria oprogramowania, VII/72

K. Bartecki, Inżynieria oprogramowania, VII/73

Przykładowy diagram obiektów

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

K. Bartecki, Inżynieria oprogramowania, VII/78

Przykładowy diagram pakietów

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

K. Bartecki, Inżynieria oprogramowania, VII/80

Przykładowy diagram pakietów

K. Bartecki, Inżynieria oprogramowania, VII/81

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

Przykłady zależności między komponentami

K. Bartecki, Inżynieria oprogramowania, VII/87

Przykłady zależności między komponentami

K. Bartecki, Inżynieria oprogramowania, VII/88

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

Przykładowy diagram komponentów

K. Bartecki, Inżynieria oprogramowania, VII/91

Przykładowy diagram komponentów

K. Bartecki, Inżynieria oprogramowania, VII/92

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

Przykładowy diagram wdrożeniowy

K. Bartecki, Inżynieria oprogramowania, VII/95

Przykładowy diagram wdrożeniowy

K. Bartecki, Inżynieria oprogramowania, VII/96

Przykładowy diagram wdrożeniowy

K. Bartecki, Inżynieria oprogramowania, VII/97

K. Bartecki, Inżynieria oprogramowania, VII/98

Przykładowy diagram wdrożeniowy