UML 2.0. Almanach
Autor: Dan Pilone, Neil Pitman
T³umaczenie: £ukasz Piwko
ISBN: 978-83-246-0822-5
Tytu³ orygina³u:
UML 2.0 in a Nutshell
Format: B5, stron: 248
Wyczerpuj¹cy przewodnik po jêzyku UML 2.0
Specyfikacja jêzyka UML 2.0
Modelowanie statyczne i dynamiczne
Rozszerzanie i zastosowania UML-a
Ujednolicony jêzyk modelowania (UML) pocz¹tkowo s³u¿y³ do opisu elementów
oprogramowania, jednak z powodu swej elegancji i przejrzystoci zyskuje na popularnoci
w zakresie modelowania zagadnieñ z innych dziedzin. W zwi¹zku z tym coraz wiêcej osób
ma szansê zetkn¹æ siê z diagramami w jêzyku UML. Jeli siêgn¹³e po tê ksi¹¿kê,
prawdopodobnie czeka to tak¿e Ciebie. Chcia³by wiedzieæ, co oznaczaj¹ ró¿ne
zakoñczenia linii na diagramach klas albo zrozumieæ skomplikowany diagram interakcji?
Zajrzyj do rodka.
UML 2.0. Almanach to kompletny podrêcznik dla u¿ytkowników tego jêzyka. Dziêki tej
ksi¹¿ce poznasz podstawy modelowania w UML-u. Nauczysz siê tworzyæ i rozumieæ
diagramy statyczne, na przyk³ad klas, pakietów czy struktur z³o¿onych, a tak¿e diagramy
zachowania, takie jak przypadków u¿ycia, aktywnoci czy interakcji. Dowiesz siê, jak
wszechstronne zastosowania ma ten jêzyk oraz w jaki sposób mo¿na go rozszerzaæ do
wykonywania specyficznych zadañ. Znajdziesz tu tak¿e krótkie wprowadzenie do jêzyka
Object Constraint Language (OCL) oraz architektury sterowanej modelem (MDA).
Podstawy modelowania w UML-u
Diagramy statyczne i diagramy zachowania
Dobór odpowiedniego rodzaju diagramu
Znaczenie symboli, notacji i linii
Rozszerzanie UML-a za pomoc¹ etykiet, stereotypów i profili
Architektura sterowana modelem
Jêzyk Object Constraint Language (OCL)
Praktyczne wskazówki z zakresu modelowania
Poznaj tajniki modelowania w jêzyku UML 2.0
5
Spis treļci
Wstýp ...............................................................................................................................9
1. Podstawy UML-a .......................................................................................................... 15
Zaczynamy
15
Historia
15
Podstawy UML-a
16
Specyfikacje UML-a
17
UĔywanie UML-a
18
Modelowanie
19
Praktyczne zasady UML-a
23
2. Diagramy klas ................................................................................................................25
Klasy
25
Atrybuty
26
Operacje
33
Metody
38
Klasy abstrakcyjne
38
Powiñzania
39
Interfejsy
44
Szablony
46
RóĔne wersje diagramów klas
48
3. Diagramy pakietów ......................................................................................................53
Reprezentacja
53
WidocznoĈè
54
Import pakietów i dostöp do nich
55
ãñczenie pakietów
56
RóĔne wersje diagramów pakietów
57
6
_
Spis treļci
4. Struktury zĥożone .........................................................................................................65
Struktury zäoĔone
65
Kolaboracje
73
Przypadki kolaboracji
75
5. Diagramy komponentów .............................................................................................. 77
Komponenty
77
Widoki komponentów
78
6. Diagramy wdrożenia ....................................................................................................87
Artefakty
87
Wözäy
89
WdraĔanie
93
Nietypowe diagramy wdroĔenia
96
7. Diagramy przypadków użycia ......................................................................................99
Przypadki uĔycia
99
Aktorzy
100
Zaawansowane modelowanie przypadków uĔycia
103
Zasiög przypadków uĔycia
108
8. Diagramy stanów ......................................................................................................... 111
Maszyny stanowe zachowaþ
111
Stany
113
Rozszerzanie maszyny stanów
123
Protokoäowe maszyny stanów
123
Pseudostany
125
Przetwarzanie zdarzeþ
126
Nietypowe diagramy stanów
127
9. Diagramy aktywnoļci ................................................................................................. 129
AktywnoĈci i akcje
129
Znaczniki sterowania
136
AktywnoĈci
137
Zaawansowane modelowanie aktywnoĈci
144
10. Diagramy interakcji ..................................................................................................... 155
Co to sñ interakcje
155
Uczestnicy interakcji
156
Komunikaty
158
Wykonywanie interakcji
163
Stany niezmienne
164
Spis treļci
_
7
Zdarzenia
166
ćlady
166
Fragmenty wyodröbnione
167
Wystñpienia interakcji
178
Dekompozycja
179
Kontynuacje
182
Przepäywy czasowe sekwencji
183
Alternatywne notacje interakcji
184
11. Metki, stereotypy i profile UML ................................................................................. 193
Modelowanie i UML w kontekĈcie
194
Stereotypy
196
Metki
198
Ograniczenia
199
Profile UML
199
Narzödzia a profile
201
12. Tworzenie efektywnych diagramów ........................................................................203
Diagramy tapetowe
203
Zbyt duĔy zakres
208
Jeden diagram — jedna abstrakcja
209
Poza UML-em
211
A MDA — Model-Driven Architecture ......................................................................... 215
Co to jest MDA
215
Modele MDA
216
Decyzje projektowe
219
ãñczenie modeli w jednñ caäoĈè
221
Transformacja modeli
222
Jözyki formalnego opisu MDA
223
B Object Constraint Language .......................................................................................225
Podstawy OCL-a
225
Skäadnia OCL-a
226
Zaawansowane modelowanie OCL-a
229
Skorowidz ....................................................................................................................233
8
_
Spis treļci
25
ROZDZIAĤ 2.
Diagramy klas
Diagramy klas naleĔñ do najbardziej podstawowych typów diagramów UML-a. Stosuje siö je
do przedstawiania statycznych powiñzaþ w programach — mówiñc inaczej: jak wszystko äñczy
siö w jednñ caäoĈè.
Piszñc program, caäy czas trzeba podejmowaè decyzje: jakie klasy przechowujñ odniesienia
do innych klas, która klasa „posiada” innñ klasö itd. Diagramy klas pozwalajñ na przedsta-
wienie fizycznej struktury systemu.
Klasy
Klasa reprezentuje grupö obiektów o wspólnym stanie i zachowaniu. Klasö moĔna traktowaè
jako plan obiektu w systemie zorientowanym obiektowo. W UML-u klasa jest rodzajem kla-
syfikatora. Na przykäad Volkswagen, Toyota i Ford to marki samochodów, a zatem moĔna je
zaprezentowaè za pomocñ klasy o nazwie
Samochód
. KaĔdy konkretny samochód jest egzem-
plarzem tej klasy, czyli obiektem. Klasa moĔe reprezentowaè konkretne namacalne obiekty, takie
jak na przykäad faktura. MoĔe byè abstrakcyjna, np. dokument lub pojazd (w odróĔnieniu np.
od faktury i motocykla o pojemnoĈci powyĔej 1000 cm
3
). MoĔe takĔe reprezentowaè obiekty nie-
materialne, takie jak np. strategia inwestycji wysokiego ryzyka.
Klasa ma postaè prostokñta podzielonego na komórki. Komórka to wydzielony obszar prosto-
kñta, do którego moĔna wpisywaè pewne informacje. Pierwsza komórka zawiera nazwö klasy,
druga atrybuty (patrz „Atrybuty”), a trzecia operacje (patrz „Operacje”). W celu zwiökszenia
czytelnoĈci diagramu moĔna ukryè wybrane komórki. Czytajñc diagram, nie moĔna domy-
Ĉlaè siö treĈci brakujñcych komórek — to, Ĕe sñ ukryte, wcale nie oznacza, Ĕe sñ puste. Do
klas moĔna wstawiaè komórki z dodatkowymi informacjami, takimi jak wyjñtki lub zdarzenia,
ale dziaäania te wykraczajñ juĔ poza typowñ notacjö.
UML proponuje nastöpujñce zasady dotyczñce nazw klas:
x
powinny byè pisane z wielkiej litery,
x
powinny byè wyĈrodkowane w górnej komórce,
x
powinny byè pisane täustym drukiem,
x
nazwy klas abstrakcyjnych powinny byè pisane kursywñ (patrz „Klasy abstrakcyjne”).
26
_
Rozdziaĥ 2. Diagramy klas
Na rysunku 2.1 przedstawiono prostñ klasö.
Rysunek 2.1. Prosta klasa
Obiekty
Obiekt jest egzemplarzem klasy. Na przykäad klasa o nazwie
Samochód
moĔe mieè kilka eg-
zemplarzy: jeden czerwony dwudrzwiowy samochód, jeden niebieski czterodrzwiowy samochód
i jeden zielony samochód typu hatchback. KaĔdy egzemplarz klasy
Samochód
jest obiektem
i moĔe mieè wäasnñ nazwö, aczkolwiek w diagramach obiektów czösto uĔywa siö obiektów
anonimowych, czyli bez nazw. Zazwyczaj po nazwie obiektu stawia siö dwukropek, a po
nim nazwö typu obiektu (tzn. klasy). Aby pokazaè, Ĕe dany obiekt jest egzemplarzem klasy,
naleĔy podkreĈliè jego nazwö i typ. Na rysunku 2.2 pokazano egzemplarz klasy
Samochód
o nazwie
Toyota
. Warto zwróciè uwagö, Ĕe na tym rysunku puste komórki zostaäy ukryte.
Rysunek 2.2. Egzemplarz klasy Samochód
Atrybuty
Szczegóäy klasy (kolor samochodu, liczba boków figury itd.) przedstawiane sñ jako atrybuty.
Atrybuty mogñ byè prostymi typami podstawowymi (liczby caäkowite, liczby zmiennopozycyjne
itd.) lub powiñzaniami do innych, bardziej skomplikowanych obiektów (patrz „Powiñzania”).
Atrybut moĔna przedstawiè przy uĔyciu jednej z dwóch dostöpnych notacji: wewnötrznej
(ang. inlined) lub powiñzaþ z innymi klasami. Ponadto dostöpna jest notacja, za pomocñ któ-
rej moĔna pokazywaè licznoĈè, unikalnoĈè oraz uporzñdkowanie. W tej czöĈci rozdziaäu opi-
sujemy oba rodzaje notacji, a nastöpnie przedstawiamy szczegóäy specyfikacji atrybutów.
Atrybuty wpisane
Atrybuty klasy moĔna wymieniè bezpoĈrednio w prostokñcie. Nazywajñ siö wtedy atrybutami
wpisanymi (ang. inlined attributes). Pomiödzy atrybutami wpisanymi a przedstawianymi za
pomocñ powiñzaþ nie ma Ĕadnych róĔnic semantycznych — ich wybór zaleĔy tylko od tego,
jak duĔo szczegóäów chcemy zaprezentowaè (lub, w przypadku typów fundamentalnych
takich jak liczby caäkowite, ile szczegóäów zdoäamy przekazaè).
Atrybuty
_
27
W celu zaprezentowania atrybutu wewnñtrz klasy naleĔy umieĈciè go w jej drugiej komórce.
Atrybuty wpisane w UML-u nazywajñ siö notacjñ atrybutów. Korzystajñ one z nastöpujñcej
notacji:
widocznoŁð / nazwa : typ licznoŁð = domyŁlna
{ĪaĬcuchy wĪaŁciwoŁci i ograniczenia}
widocznoŁð ::= {+|-|#|~}
licznoŁð ::= [górna..dolna]
Na rysunku 2.3 zademonstrowano róĔne aspekty notacji atrybutów na przykäadzie listy kilku
atrybutów.
Rysunek 2.3. Przykäadowe atrybuty
Elementy skäadni sñ nastöpujñce:
widocznoŁð
Informuje o widocznoĈci atrybutu. Do wyboru sñ nastöpujñce symbole:
+
,
-
,
#
i
~
, ozna-
czajñ one odpowiednio:
public
,
private
,
protected
i
package
(patrz „WidocznoĈè”
w rozdziale 3.).
/
Oznacza atrybut pochodny. Atrybut pochodny to taki, którego wartoĈè moĔna obliczyè na
podstawie innych atrybutów klasy. Patrz „Atrybuty pochodne”.
nazwa
Rzeczownik lub krótkie wyraĔenie stanowiñce nazwö atrybutu. Z reguäy pierwsza litera
pierwszego czäonu jest maäa, a pierwsze litery wszystkich nastöpnych czäonów sñ wielkie.
typ
Typ atrybutu w postaci innego klasyfikatora. Zazwyczaj klasa, interfejs lub typ wbudo-
wany, np.
int
.
licznoŁð
OkreĈla liczbö egzemplarzy typu atrybutu, do których odnosi siö atrybut. MoĔe nie zostaè
podany (wtedy oznacza 1), moĔe byè liczbñ caäkowitñ lub zakresem wartoĈci rozdzielo-
nych symbolem
..
podanym w nawiasach kwadratowych. Symbol
*
säuĔy do oznaczania
braku górnego limitu. Gwiazdka uĔyta samodzielnie oznacza zero lub wiöcej. Patrz
„LicznoĈè”.
domyŁlna
DomyĈlna wartoĈè atrybutu.
28
_
Rozdziaĥ 2. Diagramy klas
ĪaĬcuchy wĪaŁciwoŁci
Zbiór wäaĈciwoĈci lub znaczników, które moĔna doäñczyè do atrybutów. Sñ one zazwy-
czaj zaleĔne od kontekstu i oznaczajñ takie cechy jak porzñdek lub unikalnoĈè. Wystöpujñ
pomiödzy nawiasami klamrowymi
{}
, a znakiem rozdzielajñcym jest przecinek. Patrz
„WäaĈciwoĈci atrybutów”.
ograniczenia
Jedno lub wiöcej ograniczeþ zdefiniowanych dla atrybutu. Mogñ uĔywaè jözyka naturalnego
lub jakiejĈ gramatyki formalnej, np. OCL. Patrz „Ograniczenia”.
Atrybuty w postaci powiézaħ
Atrybuty moĔna równieĔ prezentowaè za pomocñ notacji powiñzaþ. Jej zastosowanie wiñĔe
siö z powstawaniem wiökszych diagramów, ale zapewnia wiökszñ szczegóäowoĈè w przy-
padku zäoĔonych typów atrybutów. Notacja powiñzaþ przekazuje równieĔ dokäadne infor-
macje na temat tego, jak atrybut zawarty jest wewnñtrz klasy (wiöcej informacji na temat
typów powiñzaþ znajduje siö w podrozdziale „Powiñzania”). Modelujñc na przykäad
Samochód
,
moĔna za pomocñ powiñzaþ o wiele jaĈniej pokazaè, Ĕe zawiera on
Silnik
, niĔ tylko wpisujñc
ten silnik na listö atrybutów w prostokñcie samochodu. Niemniej jednak prezentowanie na-
zwy samochodu za pomocñ powiñzaþ jest juĔ prawdopodobnie lekkñ przesadñ, gdyĔ jest ona
tylko äaþcuchem znaków.
W celu reprezentacji atrybutu za pomocñ powiñzaþ moĔna uĔyè jednego z powiñzaþ asocja-
cyjnych pomiödzy klasñ zawierajñcñ atrybut a reprezentujñcñ go, co pokazano na rysunku 2.4.
Widaè, Ĕe powiñzanie pomiödzy samochodem a jego silnikiem ma licznoĈè 1 — samochód
ma jeden silnik.
Rysunek 2.4. Przedstawienie atrybutu za pomocñ notacji powiñzaþ
Tak, tak — mój redaktor mówi, Ĕe niektóre samochody, jak na przykäad Toyota
Prius, majñ dwa silniki.
Notacja powiñzaþ posäuguje siö takñ samñ skäadniñ jak notacja wewnötrzna, aczkolwiek ukäad
jest nieco inny. WidocznoĈè atrybutu i jego nazwa umieszczone sñ w pobliĔu linii powiñzania.
Dla licznoĈci nie naleĔy stosowaè nawiasów kwadratowych — naleĔy jñ podawaè w pobliĔu
klasyfikatora atrybutu.
Atrybuty
_
29
Podobnie jak licznoĈè, dla atrybutów moĔna zdefiniowaè ograniczenia (patrz „Ograniczenia”).
W notacji powiñzaþ ograniczenia wpisuje siö w pobliĔu klasyfikatora atrybutu wzdäuĔ linii
powiñzania. Za pomocñ notacji powiñzaþ w UML-u moĔna równieĔ wyraĔaè ograniczenia
pomiödzy atrybutami, jak pokazano na rysunku 2.5.
Rysunek 2.5. Notacja powiñzaþ przy uĔyciu ograniczeþ
Na rysunku 2.5 standardowe ograniczenie UML-a
xor
pokazuje, Ĕe w danym czasie moĔe
byè ustawiona tylko
automatycznaSkrzyniaBiegów
albo
rĂcznaSkrzyniaBiegów
(alternatywa
wykluczajñca — exclusive
or
). W przypadku zastosowania notacji wewnötrznej konieczne
byäoby umieszczenie tego ograniczenia na notce.
Atrybuty pochodne
Notacja pochodna, którñ oznacza symbol ukoĈnika (
/
), moĔe byè uĔywana jako wskazówka
dla implementatora, Ĕe dany atrybut nie jest konieczny. PrzypuĈèmy na przykäad, Ĕe mode-
lujemy rachunek bankowy za pomocñ prostej klasy o nazwie
Rachunek
. Klasa ta przechowuje
saldo bieĔñce jako liczbö zmiennopozycyjnñ o nazwie
saldo
. Aby Ĉledziè informacjö, czy stan
konta nie zostaä przekroczony, dodajemy wartoĈè logicznñ (
boolean
) o nazwie
przekroczenie
.
O tym, czy stan konta nie zostaä przekroczony, informuje dodatnie saldo, a nie dodana przed chwilñ
wartoĈè logiczna. MoĔna o tym poinformowaè programistö, pokazujñc, Ĕe
przekroczenie
jest
atrybutem pochodnym, którego stan opiera siö na saldzie. Na rysunku 2.6 pokazano sposób
prezentacji atrybutów
saldo
i
przekroczenie
z ukazaniem powiñzania za pomocñ notki.
Rysunek 2.6. Atrybut pochodny
W specyfikacji UML-a zaznaczono, Ĕe atrybuty pochodne sñ tylko do odczytu (
readOnly
), co
oznacza, Ĕe uĔytkownik nie moĔe zmieniaè ich wartoĈci. JeĔeli jednak uĔytkownik ma po-
zwolenie na modyfikacjö ich wartoĈci, to klasa powinna odpowiednio zaktualizowaè Ēródäo
informacji pochodnej.
30
_
Rozdziaĥ 2. Diagramy klas
Licznoļë atrybutu
LicznoĈè atrybutu okreĈla liczbö egzemplarzy typu tego atrybutu utworzonych w procesie
instancjonowania klasy. Na przykäad nasz klasowy
Samochód
bödzie najprawdopodobniej
miaä cztery koäa, a wiöc licznoĈè atrybutu
koĪa
bödzie wynosiäa 4. JeĔeli licznoĈè nie zostaäa
okreĈlona, to domyĈlnie wynosi 1. LicznoĈè moĔe byè pojedynczñ liczbñ caäkowitñ, listñ liczb
caäkowitych oddzielanych przecinkami lub zakresem wartoĈci. W przypadku zakresu warto-
Ĉci nieskoþczonoĈè dodatnia jest reprezentowana za pomocñ symbolu
*
. JeĔeli dolna granica
nie zostanie podana, symbol
*
oznacza zero lub wiöcej. WartoĈè licznoĈci podawana jest po-
miödzy nawiasami kwadratowymi w postaci pojedynczej liczby caäkowitej lub za pomocñ
dwóch liczb caäkowitych rozdzielonych dwiema kropkami (
..
). Na rysunku 2.7 przedstawiono
róĔne sposoby reprezentacji licznoĈci atrybutu.
Rysunek 2.7. Przykäady licznoĈci
Porzédek
Atrybut, którego licznoĈè przekracza 1, moĔe byè sortowany (ang. ordered). W takim przypadku
elementy muszñ byè przechowywane w odpowiedniej kolejnoĈci. MoĔna na przykäad zdecy-
dowaè siö na przechowywanie listy nazwisk w kolejnoĈci alfabetycznej, nadajñc jej wäaĈci-
woĈè
ordered
. Co dokäadnie oznacza przechowywanie elementów w odpowiedniej kolejnoĈci,
zaleĔy od rodzaju atrybutu. DomyĈlnie atrybuty nie sñ sortowane. Aby oznaczyè atrybut jako
sortowany, naleĔy po nim dodaè wäaĈciwoĈè
ordered
, jak widaè na rysunku 2.8.
Rysunek 2.8. LicznoĈè sortowana
Unikalnoļë
Poza sortowaniem atrybuty o licznoĈci powyĔej 1 mogñ byè równieĔ unikalne (ang. unique).
JeĔeli atrybut ma byè unikalny, to wszystkie jego elementy równieĔ muszñ takie byè.
DomyĈlnie wszystkie atrybuty o licznoĈci powyĔej 1 sñ unikalne. Oznacza to, Ĕe Ĕaden z ele-
mentów atrybutu nie moĔe siö powtarzaè. Na przykäad jeĔeli klasa przechowywaäaby listö
osób biorñcych udziaä w gäosowaniu i kaĔdy gäosujñcy miaäby tylko jeden gäos, to kaĔdy ele-
ment takiej listy byäby unikalny. Aby uczyniè atrybut unikalnym, naleĔy umieĈciè po nim
Atrybuty
_
31
w nawiasach klamrowych säowo kluczowe
unique
, jak pokazano na rysunku 2.9. Aby ze-
zwoliè na przechowywanie powtarzajñcych siö obiektów przez atrybut, naleĔy uĔyè säowa
kluczowego
not unique
.
Rysunek 2.9. LicznoĈè unikalna
Typy kolekcji
Specyfikacja UML-a okreĈla zestaw odwzorowaþ róĔnych wäaĈciwoĈci sortowania i unikalnoĈci
do typów kolekcji UML-a. W tabeli 2.1 przedstawiono odwzorowania wäaĈciwoĈci atrybutów
do typów kolekcji UML-a. NaleĔy pamiötaè, Ĕe typy kolekcji zaprezentowane w tabeli 2.1 sñ
odwzorowaniami UML-a i nie mogñ byè przekäadane bezpoĈrednio na klasy jözyka docelowego.
Tabela 2.1. Typy kolekcji atrybutów
Sortowanie
Unikalnoļë
Typ skojarzonej kolekcji
False
False
Bag
True
True
OrderedSet
False
True
Set
True
False
Sequence
Na przykäad aby pokazaè, Ĕe klienci banku powinni zostaè zaprezentowani za pomocñ ko-
lekcji
OrderedSet
, model atrybutu
klienci
mógäby wyglñdaè jak na rysunku 2.10.
Rysunek 2.10. Przykäadowy atrybut przechowywany w kolekcji OrderedSet
Wĥaļciwoļci atrybutów
Poza wäaĈciwoĈciami zwiñzanymi z licznoĈciñ atrybut moĔe mieè jeszcze kilka innych wäa-
ĈciwoĈci pozwalajñcych przekazaè czytelnikowi diagramu dodatkowe informacje. NajczöĈciej
uĔywane wäaĈciwoĈci zdefiniowane w UML-u to:
readOnly
Oznacza, Ĕe nie moĔna modyfikowaè poczñtkowo nadanej wartoĈci atrybutu. W jözyku,
w którym tworzony jest program, wäaĈciwoĈè ta najczöĈciej znajduje odwzorowanie w po-
staci staäej. UML nie narzuca, kiedy naleĔy podaè wartoĈè poczñtkowñ. Aczkolwiek jeĔeli
dla atrybutu zostanie podana wartoĈè domyĈlna, to jest ona traktowana jako poczñtkowa
i nie moĔe byè zmieniana.
32
_
Rozdziaĥ 2. Diagramy klas
union
Oznacza, Ĕe typ atrybutu jest uniñ wartoĈci dozwolonych dla tego atrybutu. WäaĈciwoĈè
ta jest czösto uĔywana w poäñczeniu z wäaĈciwoĈciñ
derived
w celu zaznaczenia, Ĕe atrybut
jest uniñ pochodnñ od innego zbioru atrybutów.
subsets <nazwa-atrybutu>
Oznacza, Ĕe ten typ atrybutu jest podzbiorem wszystkich prawidäowych wartoĈci tego
atrybutu. WäaĈciwoĈè ta nie jest zbyt czösto uĔywana, ale jeĔeli juĔ zostanie uĔyta, to za-
zwyczaj jest zwiñzana z podklasami typu atrybutu.
redefines <nazwa-atrybutu>
Oznacza, Ĕe ten atrybut stanowi alias danego atrybutu. WäaĈciwoĈè ta nie jest czösto uĔy-
wana, ale moĔe mieè zastosowanie do pokazania, Ĕe jakaĈ podklasa ma atrybut bödñcy
aliasem atrybutu klasy nadrzödnej.
composite
Oznacza, Ĕe ten atrybut jest czöĈciñ zwiñzku caäoĈè-czöĈè z klasyfikatorem. Wiöcej infor-
macji o kompozycjach znajduje siö w podrozdziale „Powiñzania”.
Ograniczenia
Ograniczenia stanowiñ pewne ĈciĈlejsze zasady dotyczñce elementów. Mogñ byè pisane w jözyku
naturalnym lub przy uĔyciu gramatyk formalnych, np. OCL. Muszñ mieè jednak wartoĈè
logicznñ. Zazwyczaj ograniczenia umieszcza siö w nawiasach klamrowych po elemencie,
do którego siö odnoszñ, ale moĔna je takĔe umieszczaè w notkach doäñczanych do niego za
pomocñ linii przerywanej.
Nazwö ograniczenia podaje siö po dwukropku (
:
) przed wyraĔeniem logicznym. Jest to czösty
sposób identyfikacji ograniczeþ operacji (patrz „Ograniczenia operacji”).
Na rysunku 2.11 przedstawiono kilka ograniczeþ dla atrybutów i operacji.
Rysunek 2.11. Przykäady ograniczeþ wpisanych i umieszczonych na notkach
Operacje
_
33
Atrybuty statyczne
Atrybuty statyczne sñ atrybutami klas, a nie ich egzemplarzy. MoĔna na przykäad zainicjali-
zowaè staäe wartoĈci dla klasy, a nastöpnie udostöpniè je wszystkim jej egzemplarzom. Atry-
buty statyczne reprezentowane sñ za pomocñ podkreĈlenia ich specyfikacji zarówno w notacji
wewnötrznej, jak i w prezentacjach opartych na powiñzaniach. Pokazano to na rysunku 2.12.
Rysunek 2.12. Atrybut statyczny
Operacje
Operacje to wäaĈciwoĈci klas, które okreĈlajñ, w jaki sposób wywoäaè okreĈlone zachowanie.
Na przykäad klasa moĔe zawieraè operacjö rysujñcñ na ekranie prostokñt lub sprawdzajñcñ
liczbö elementów wybranych z listy. W UML-u istnieje wyraĒne rozróĔnienie pomiödzy
okreĈleniem, jak wywoäaè zachowanie (operacja), a rzeczywistñ implementacjñ tego zacho-
wania (metoda). W celu uzyskania wiökszej iloĈci informacji patrz podrozdziaä „Metody”.
Operacje umieszcza siö w oddzielnych komórkach przy uĔyciu nastöpujñcej skäadni:
widocznoŁð nazwa ( parametry ) : typ-zwracany {wĪaŁciwoŁci}
gdzie parametry zapisuje siö nastöpujñco:
kierunek nazwa_parametru : typ [ licznoŁð ]
= wartoŁð_domyŁlna { wĪaŁciwoŁci }
Na rysunku 2.13 przedstawiono kilka przykäadowych operacji klasy.
Rysunek 2.13. Przykäadowe operacje klasy
34
_
Rozdziaĥ 2. Diagramy klas
Elementy skäadni sñ nastöpujñce:
widocznoŁð
OkreĈla widocznoĈè operacji. Do wyboru sñ nastöpujñce symbole:
+
,
-
,
#
i
~
, oznaczajñ one
odpowiednio:
public
,
private
,
protected
i
package
(patrz „WidocznoĈè” w rozdziale 3.).
nazwa
Krótkie wyraĔenie stanowiñce nazwö operacji. Operacje sñ zazwyczaj wyraĔeniami cza-
sownikowymi reprezentujñcymi czynnoĈci, które klasyfikator powinien wykonaè w imieniu
wywoäujñcego. W specyfikacji UML-a zaleca siö, aby pierwsza litera pierwszego czäonu
byäa maäa, a pierwsze litery wszystkich nastöpnych czäonów wielkie. Przykäad pokazano
na rysunku 2.13.
typ-zwracany
OkreĈla rodzaj informacji zwracanej przez operacjö (jeĔeli operacja coĈ zwraca). JeĔeli ope-
racja nie zwraca Ĕadnych danych (w niektórych jözykach programowania zwana jest
w takich przypadkach podprogramem), to typem zwracanym powinien byè
void
. JeĔeli
jednak operacja zwraca jakñĈ wartoĈè (w niektórych jözykach programowania zwana jest
wtedy funkcjñ), to naleĔy pokazaè typ tej wartoĈci, np. inny klasyfikator, typ podstawo-
wy lub kolekcja. Specyfikacja UML-a stanowi, Ĕe podawanie typu zwracanego jest opcjo-
nalne. JeĔeli typ zwracany nie zostanie podany, nie moĔna go odgadnñè, a nawet nie wia-
domo, czy istnieje.
wĪaŁciwoŁci
OkreĈla ograniczenia i wäaĈciwoĈci operacji. Pole to jest opcjonalne. W przypadku nie-
uĔywania wäaĈciwoĈci nie wpisuje siö nawiasów klamrowych. Wiöcej informacji na ten
temat moĔna znaleĒè w podrozdziale „Ograniczenia operacji”.
Elementy skäadni parametru sñ nastöpujñce:
kierunek
Opcjonalny element skäadni, który informuje, w jaki sposób parametr jest uĔywany przez
operacjö. Dostöpne wartoĈci to:
in
,
inout
,
out
oraz
return
.
in
oznacza, Ĕe parametr jest
przekazywany do operacji przez wywoäujñcego;
inout
, Ĕe parametr jest przekazywany
przez wywoäujñcego, a nastöpnie prawdopodobnie modyfikowany przez operacjö i wy-
syäany z powrotem;
out
, Ĕe parametr nie jest ustawiany przez wywoäujñcego, ale przez
operacjö i jest przekazywany z powrotem na zewnñtrz;
return
oznacza natomiast, Ĕe
wartoĈè ustawiona przez wywoäujñcego jest przekazywana z powrotem na zewnñtrz jako
wartoĈè zwracana.
nazwa_parametru
Jest rzeczownikiem lub wyraĔeniem rzeczownikowym stanowiñcym nazwö parametru.
Zazwyczaj nazwa parametru rozpoczyna siö z maäej litery, a nastöpne skäadajñce siö na niñ
wyrazy zaczynajñ siö od wielkich liter.
typ
Typ parametru. Zazwyczaj jest to inna klasa, interfejs, kolekcja lub typ podstawowy.
licznoŁð
OkreĈla liczbö obecnych egzemplarzy typu parametru. MoĔe nie zostaè podana (wtedy
oznacza 1), moĔe byè liczbñ caäkowitñ, zakresem wartoĈci rozdzielonych przecinkami lub
zakresem wartoĈci podanym w nawiasach kwadratowych i rozdzielonych symbolem
..
.
Symbol
*
säuĔy do oznaczania górnego limitu. JeĔeli uĔyty jest samodzielnie, oznacza zero
lub wiöcej. Patrz „LicznoĈè”.
Operacje
_
35
wartoŁð_domyŁlna
OkreĈla wartoĈè domyĈlnñ tego parametru. WartoĈè domyĈlna jest opcjonalna. JeĔeli nie
zostanie podana, to nie naleĔy wstawiaè znaku równoĈci. NaleĔy zwróciè uwagö, Ĕe UML
nie okreĈla, czy parametr z wartoĈciñ domyĈlnñ moĔe zostaè pominiöty podczas wywo-
äywania operacji (np. implementacja wartoĈci domyĈlnych parametrów w C++). Rzeczy-
wista skäadnia wywoäywania operacji jest zaleĔna od konkretnego jözyka programowania.
wĪaŁciwoŁci
OkreĈla wszelkie wäaĈciwoĈci odnoszñce siö do parametru. Element ten podawany jest w na-
wiasach klamrowych. WäaĈciwoĈci definiuje siö zazwyczaj w kontekĈcie okreĈlonego modelu,
ale jest kilka wyjñtków:
ordered
,
readOnly
oraz
unique
. W celu zdobycia wiökszej iloĈci
informacji zajrzyj do podrozdziaäów „LicznoĈè” i „WäaĈciwoĈci atrybutów”. WäaĈciwoĈci
sñ opcjonalne. JeĔeli nie ma Ĕadnych, to nie naleĔy wstawiaè nawiasów klamrowych.
Ograniczenia operacji
Z operacjñ moĔe byè skojarzonych kilka ograniczeþ, które pomagajñ zdefiniowaè sposób jej
interakcji z resztñ systemu. Razem wziöte ograniczenia operacji stanowiñ kontrakt, który musi
byè przestrzegany w implementacji operacji.
Ograniczenia operacji wykorzystujñ zwykäñ notacjö i umieszczane sñ albo bezpoĈrednio po
sygnaturze operacji, albo w notce doäñczonej za pomocñ linii przerywanej. Wiöcej informacji
na ten temat moĔna znaleĒè w podrozdziale „Ograniczenia”.
Warunki wstýpne
Warunki wstöpne (ang. preconditions) precyzujñ to, w jakim stanie powinien znajdowaè siö
system przed wywoäaniem operacji. Z praktycznego punktu widzenia nie da siö wyraziè stanu
caäego systemu. W zwiñzku z tym warunki wstöpne zazwyczaj okreĈlajñ prawidäowe wartoĈci
parametrów, stan klasy zawierajñcej operacjö lub kilka atrybutów kluczowych dla systemu.
W specyfikacji jasno napisano, Ĕe operacja nie musi sprawdzaè warunków wstöpnych w jej ciele
przed wykonaniem. Teoretycznie operacja nie zostanie nawet wywoäana, jeĔeli warunki wstöpne
nie zostanñ speänione. W praktyce niewiele jözyków programowania umoĔliwia takñ ochronö.
JeĔeli ktoĈ poĈwiöciä czas na zdefiniowanie warunków wstöpnych, to najczöĈciej w interesie
programisty jest sprawdzenie, czy podczas implementacji operacji sñ one prawidäowe.
Warunki wstöpne dajñ deweloperowi jednñ z niewielu okazji do chronienia wäasnego stano-
wiska i dokäadnego wyraĔenia, jak powinno wszystko wyglñdaè po wywoäaniu implementacji.
NaleĔy je stosowaè.
Na rysunku 2.14 przedstawiono kilka przykäadowych warunków wstöpnych.
Rysunek 2.14. Warunki wstöpne operacji
36
_
Rozdziaĥ 2. Diagramy klas
Warunki koħcowe
Warunki koþcowe okreĈlajñ gwarancje na temat stanu systemu po wykonaniu operacji.
Podobnie jak warunki wstöpne, warunki koþcowe zazwyczaj wyraĔajñ stan jednego lub
wiökszej liczby kluczowych atrybutów systemu albo pewnñ gwarancjö na temat stanu klasy
zawierajñcej operacjö.
Rysunek 2.15 przedstawia przykäadowe warunki koþcowe doäñczone do operacji.
Rysunek 2.15. Warunki koþcowe doäñczone do operacji
Warunki ciaĥa operacji
Operacja moĔe mieè
warunekCiaĪa
käadñcy ograniczenia na typ zwracany. Jest on oddzielo-
ny od warunków koþcowych, poniewaĔ moĔe zostaè zastñpiony metodami podklas klasy
nadrzödnej (wiöcej informacji na temat podklas znajduje siö w podrozdziale „Generalizacje”).
Na przykäad klasa o nazwie
Okno
moĔe definiowaè warunek ciaäa operacji dla metody o na-
zwie
sprawdşRozmiar()
, który bödzie pilnowaä, aby däugoĈè i szerokoĈè okna nie miaäy
wartoĈci zerowych. Podklasa o nazwie
KwadratoweOkno
moĔe mieè wäasny warunek ciaäa
operacji okreĈlajñcy, Ĕe szerokoĈè musi byè równa däugoĈci.
warunekCiaĪa
jest podobny do
warunku wejĈciowego i koþcowego w tym, Ĕe moĔna go wyraziè zarówno w jözyku naturalnym,
jak i w OCL-u (patrz „Ograniczenia”). Rysunek 2.16 przedstawia przykäadowy
warunekCiaĪa
operacji.
Rysunek 2.16. Warunki ciaäa operacji
Operacje
_
37
Operacje odpytujéce
Operacjö moĔna zadeklarowaè jako odpytujñcñ, jeĔeli jej implementacja nie powoduje Ĕadnych
modyfikacji klasy nadrzödnej. W praktyce twórcy modeli czösto uĔywajñ wäaĈciwoĈci odpy-
tywania do oznaczania metod, które nie modyfikujñ Ĕadnego znaczñcego atrybutu obiektu.
Mogñ na przykäad istnieè wewnötrzne atrybuty pamiöci podröcznej, które podlegajñ uaktual-
nieniom w wyniku wykonania jakiegoĈ zapytania. WaĔne jest, Ĕe stan systemu, z zewnötrz-
nej perspektywy, nie ulega zmianie w wyniku wykonania metody zapytania. Wywoäanie tej
metody nie moĔe mieè Ĕadnych skutków ubocznych.
Metodö zapytania sygnalizuje siö poprzez umieszczenie ograniczenia zapytania po sygnaturze
operacji. Na przykäad operacja o nazwie
sprawdşWiek()
zwracajñca tylko liczbö caäkowitñ,
a niezmieniajñca Ĕadnych wewnötrznych wartoĈci zawierajñcej jñ klasy moĔe byè uznana za
operacjö odpytujñcñ. W jözyku C++ operacje tego typu znajdujñ odwzorowanie w postaci
metod typu
const
. Na rysunku 2.17 przedstawiono kilka metod odpytujñcych klasy.
Rysunek 2.17. Przykäadowe operacje odpytujñce
Wyjétki
Mimo Ĕe wyjñtki powodowane przez operacje z technicznego punktu widzenia nie sñ tym
samym co ograniczenia, moĔna je definiowaè przy uĔyciu takiej samej notacji. PrzewaĔnie
wyjñtki sñ innymi klasami (czösto zaklasyfikowane sñ za pomocñ säowa kluczowego
«exception»
,
ale to tylko ze wzglödu na konwencjö) powodowanymi przez operacjö w przypadku wystñ-
pienia bäödu. Listö spowodowanych wyjñtków moĔna umieĈciè w notce doäñczonej do operacji
za pomocñ linii przerywanej. Na rysunku 2.18 pokazano przykäadowñ operacjö powodujñcñ
kilka wyjñtków.
Rysunek 2.18. Metoda powodujñca kilka wyjñtków
38
_
Rozdziaĥ 2. Diagramy klas
Operacje statyczne
Operacje z reguäy okreĈlajñ zachowanie egzemplarza klasy. ChociaĔ UML pozwala takĔe na
okreĈlanie zachowania samych klas za pomocñ operacji. Operacje takie noszñ nazwö operacji
statycznych i wywoäywane sñ bezpoĈrednio dla klas, a nie dla ich egzemplarzy. Operacje sta-
tyczne sñ czösto uĔywane jako operacje uĔytkowe, które nie muszñ wykorzystywaè atrybutów
klasy nadrzödnej. W UML-u nie ma formalnego opisu notacji dla tych operacji, aczkolwiek
na ogóä sñ one reprezentowane przy uĔyciu tych samych konwencji co atrybuty statyczne.
Aby oznaczyè operacjö jako statycznñ, naleĔy jñ podkreĈliè. Rysunek 2.19 przedstawia przy-
käadowñ operacjö statycznñ.
Rysunek 2.19. Klasa z operacjñ statycznñ
Metody
Metoda jest implementacjñ operacji. Z reguäy kaĔda klasa dostarcza implementacji swoich
operacji lub dziedziczy je od swojej klasy nadrzödnej (patrz „Generalizacje”). JeĔeli klasa nie
dostarcza implementacji jakiejĈ operacji i brakuje jej teĔ w klasie nadrzödnej, to operacja jest
abstrakcyjna (patrz „Klasy abstrakcyjne”). Jako Ĕe metody sñ implementacjami operacji, nie
majñ wäasnej notacji. Ilustrujñ one operacje na klasie.
Klasy abstrakcyjne
Klasa abstrakcyjna to z reguäy klasa, która dostarcza sygnatury operacji, ale nie jej implementacjö.
MoĔna takĔe utworzyè klasö abstrakcyjnñ nieposiadajñcñ Ĕadnych operacji. Klasy abstrakcyjne
sñ przydatne do identyfikacji wspólnej funkcjonalnoĈci obiektów kilku typów. MoĔna na przy-
käad utworzyè klasö abstrakcyjnñ o nazwie
Ruchomy
.
Ruchomy
obiekt to taki, który ma jakieĈ
bieĔñce poäoĔenie i moĔe byè przesuwany za pomocñ operacji o nazwie
przesuĬ()
. Klasa ta
moĔe mieè kilka specjalizacji, np.:
Samochód
,
KonikPolny
i
Osoba
, z których kaĔda ma wäasnñ
implementacjö operacji
przesuĬ()
. Jako Ĕe klasa bazowa
Ruchomy
nie ma implementacji ope-
racji
przesuĬ()
, jest klasñ abstrakcyjnñ.
Klasy abstrakcyjne oznacza siö, piszñc ich nazwy kursywñ (tak samo jak operacje abstrakcyjne).
Na rysunku 2.20 przedstawiono przykäad klasy abstrakcyjnej
Ruchomy
.
Rysunek 2.20. Klasa abstrakcyjna
Powiézania
_
39
Klasa abstrakcyjna nie moĔe tworzyè obiektów. Aby byäo to moĔliwe, najpierw naleĔy utwo-
rzyè jej podklasö implementujñcñ operacjö i dopiero od tej podklasy utworzyè obiekty. Wiöcej
na temat podklas moĔna znaleĒè w podrozdziale „Powiñzania”.
Powiézania
Same klasy nie dostarczyäyby zbyt wielu informacji na temat projektu systemu. W UML-u
dostöpnych jest kilka sposobów reprezentacji powiñzaþ pomiödzy klasami. KaĔde powiñza-
nie UML reprezentuje inny typ poäñczenia pomiödzy klasami i ma subtelne wäaĈciwoĈci, któ-
re nie zostaäy w peäni ujöte w specyfikacji UML-a. Tworzñc modele w Ĉwiecie rzeczywistym,
naleĔy upewniè siö, Ĕe informacje przekazywane za pomocñ powiñzaþ sñ zrozumiaäe dla od-
biorcy. Jest to zarówno ostrzeĔenie dla tworzñcych modele, jak i nasze wyjaĈnienie, Ĕe to, co
piszemy poniĔej, stanowi naszñ wäasnñ interpretacjö specyfikacji UML-a. Na przykäad dysku-
sja na temat tego, kiedy uĔywaè agregacji, a kiedy kompozycji, caäy czas siö toczy. Aby po-
móc wybraè najlepsze powiñzanie, podajemy krótkñ frazö dla kaĔdego typu, która usprawnia
dokonywanie rozróĔnienia. NajwaĔniejsze jest utrzymanie spójnoĈci modelu.
Zależnoļci
Najsäabszym rodzajem powiñzaþ miödzy klasami sñ zaleĔnoĈci. ZaleĔnoĈè pomiödzy klasami
oznacza, Ĕe jedna klasa uĔywa drugiej klasy lub ma dotyczñce niej informacje. Zwiñzek taki
jest zazwyczaj krótkotrwaäy. Oznacza to, Ĕe klasa zaleĔna wchodzi w krótkñ interakcjö z klasñ
docelowñ, ale z reguäy nie utrzymuje z niñ zwiñzku przez realnñ iloĈè czasu.
ZaleĔnoĈci zazwyczaj czytamy jako „…uĔywa…”. Na przykäad jeĔeli mielibyĈmy klasö
Okno
wysyäajñcñ klasö o nazwie
ZamykanieOkna
w momencie, gdy ma ono zostaè zamkniöte, po-
wiedzielibyĈmy:
Okno
uĔywa
ZamykanieOkna
.
ZaleĔnoĈci pomiödzy klasami oznacza siö liniñ przerywanñ zakoþczonñ strzaäkñ wskazujñcñ
od klasy zaleĔnej do uĔywanej. Na rysunku 2.21 pokazano zaleĔnoĈè pomiödzy klasñ o nazwie
Okno
a tñ o nazwie
ZamykanieOkna
.
Rysunek 2.21. ZaleĔnoĈè klasy Okno od klasy ZamykanieOkna
Przyglñdajñc siö powyĔszemu rysunkowi, moĔna wyciñgnñè wniosek, Ĕe klasa
Okno
nie po-
zostaje w däuĔszym zwiñzku z klasñ
ZamykanieOkna
. Wykorzystuje jñ tylko wtedy, gdy jest
jej potrzebna, a nastöpnie o niej „zapomina”.
Asocjacje
Asocjacje sñ silniejszym typem powiñzaþ niĔ zaleĔnoĈci i zazwyczaj oznaczajñ däuĔszy okres trwania
zwiñzku pomiödzy dwiema klasami. Czasy Ĕycia obiektów zwiñzanych asocjacjñ nie sñ ze sobñ
powiñzane (co oznacza, Ĕe jeden z nich moĔe zostaè zniszczony bez potrzeby niszczenia drugiego).
40
_
Rozdziaĥ 2. Diagramy klas
Asocjacje zazwyczaj czyta siö nastöpujñco: „…ma…”. Na przykäad gdybyĈmy mieli klasö
o nazwie
Okno
, która miaäaby odniesienie do bieĔñcego kursora myszy, to moglibyĈmy po-
wiedzieè
Okno
ma
Kursor
. NaleĔy zauwaĔyè róĔnicö pomiödzy wyraĔeniami „…ma…”
a „…posiada…” (patrz „Agregacje”). W tym przypadku klasa
Okno
nie jest wäaĈcicielem klasy
Kursor
, poniewaĔ jest ona wspóädzielona przez wszystkie aplikacje w systemie. Ma jednak
do niej odniesienie, dziöki czemu moĔe jñ ukrywaè, modyfikowaè, ksztaätowaè itd. Asocjacje
oznacza siö jednolitñ liniñ umieszczonñ pomiödzy klasami. Na rysunku 2.22 pokazano asocjacjö
pomiödzy klasami
Okno
i
Kursor
.
Rysunek 2.22. Asocjacja ilustrujñca wyraĔenie Okno ma Kursor
Komunikacyjnoļë
Asocjacje majñ specjalnñ notacjö säuĔñcñ do obrazowania moĔliwoĈci nawigacji. JeĔeli jedna
klasa moĔe komunikowaè siö z drugñ, to oznacza siö to strzaäkñ wskazujñcñ w stronö klasy,
z którñ moĔna siö skomunikowaè. JeĔeli komunikacja moĔe zachodziè w obie strony, po-
wszechnie przyjöto, Ĕe nie rysuje siö Ĕadnych strzaäek. Specyfikacja UML-a mówi jednak, Ĕe
jeĔeli wszystkie strzaäki zostanñ pominiöte, to nie bödzie siö daäo odróĔniè asocjacji komuni-
kacyjnych od niekomunikacyjnych. Jednak asocjacje niekomunikacyjne sñ niezmiernie rzadko
stosowane, a wiöc sytuacja taka jest bardzo maäo prawdopodobna.
MoĔna zabroniè jednej klasie komunikowania siö z innñ. W tym celu naleĔy umieĈciè symbol
X
na linii asocjacyjnej przy koþcu naleĔñcym do klasy, z którñ nie moĔna siö komunikowaè.
Na rysunku 2.23 pokazano asocjacjö pomiödzy klasñ o nazwie
Okno
a tñ o nazwie
Kursor
.
Ze wzglödu na fakt, Ĕe egzemplarze klasy
Kursor
nie mogñ komunikowaè siö z egzemplarzami
klasy
Okno
, zostaäa zastosowana strzaäka z jednej strony i symbol
X
z drugiej.
Rysunek 2.23. Asocjacja pomiödzy klasami Okno i Kursor zabraniajñca nawigacji z klasy Okno do Kursor
Nazywanie asocjacji
Asocjacje moĔna ozdobiè za pomocñ kilku symboli dodajñcych pewne informacje do modelu.
Najprostszym symbolem jest jednolity grot strzaäki wskazujñcy kierunek, w którym odczy-
tujñcy powinien podñĔaè, czytajñc asocjacjö. Do grota czösto dodawane sñ krótkie wyraĔenia
dostarczajñce pewnych informacji kontekstowych dotyczñcych asocjacji. WyraĔenia te rzadko
znajdujñ odwzorowanie w kodzie Ēródäowym. SäuĔñ one wyäñcznie do celów modelowania.
Na rysunku 2.24 przedstawiono jednolity grot strzaäki zastosowany w asocjacji
Okno
-
Kursor
.
Powiézania
_
41
Rysunek 2.24. Wskazuje kierunek czytania asocjacji pomiödzy klasami Okno i Kursor
Licznoļë
Jako Ĕe asocjacje zazwyczaj reprezentujñ trwaäe zwiñzki, czösto sñ uĔywane do wskazywania
atrybutów klas. Jak pamiötamy z podrozdziaäu „Atrybuty powiñzaþ”, moĔna pokazaè, ile
egzemplarzy okreĈlonej klasy jest zaangaĔowanych w dany zwiñzek. W przypadku niepoda-
nia Ĕadnej wartoĈci, zakäada siö, Ĕe jest to 1. Aby zastosowaè innñ wartoĈè, wystarczy w po-
bliĔu posiadanej klasy umieĈciè specyfikacjö licznoĈci (informacje na temat dozwolonych typów
licznoĈci znajdujñ siö w podrozdziale „LicznoĈè atrybutu”). NaleĔy zwróciè uwagö, Ĕe w przy-
padku okreĈlania licznoĈci w asocjacjach wartoĈci nie umieszcza siö w nawiasach kwadratowych.
Rysunek 2.25 prezentuje asocjacjö z okreĈlonñ licznoĈciñ.
Rysunek 2.25. Prosta asocjacja pokazujñca 4 przyciski w oknie
WäaĈciwoĈci zwiñzane z licznoĈciñ mogñ byè stosowane równieĔ do asocjacji. Nazwy i defini-
cje dozwolonych wäaĈciwoĈci moĔna znaleĒè w podrozdziale „WäaĈciwoĈci atrybutów”.
Agregacje
Agregacja jest silniejszñ wersjñ asocjacji. Jednak w przeciwieþstwie do asocjacji z reguäy za-
käada posiadanie i moĔe implikowaè zwiñzek pomiödzy czasami Ĕycia obiektów. Agregacje
odczytuje siö nastöpujñco: „…posiada…”. Na przykäad jeĔeli klasa o nazwie
Okno
przechowuje
dane dotyczñce swojego poäoĔenia i rozmiaru w klasie
Prostokît
, to moĔna powiedzieè:
Okno
posiada
Prostokît
. Prostokñt ten moĔe byè wspóädzielony przez inne klasy, ale
Okno
pozostaje z nim w bardzo Ĉcisäym zwiñzku. RóĔnica w porównaniu z podstawowñ asocjacjñ
jest bardzo subtelna — agregacja ma silniejszñ konotacjö. Nie jest to jednakĔe najsilniejszy rodzaj
powiñzania miödzyklasowego. JeĔeli zwiñzek polega na tym, Ĕe jedna klasa jest czöĈciñ drugiej,
to nazywa siö go kompozycjñ.
Agregacjö oznacza siö za pomocñ figury w ksztaäcie diamentu, umieszczonej przy klasie po-
siadajñcej i linii ciñgäej wskazujñcej klasö posiadanñ. Na rysunku 2.26 przedstawiono agregacjö
pomiödzy klasñ o nazwie
Okno
a klasñ o nazwie
Prostokît
.
Jako Ĕe jest to zwiñzek asocjacyjny, na linii agregacyjnej moĔna umieszczaè informacje doty-
czñce komunikacyjnoĈci i licznoĈci. Patrz podrozdziaä „Asocjacje”.
42
_
Rozdziaĥ 2. Diagramy klas
Rysunek 2.26. Okno posiada Prostokñt
Kompozycje
Kompozycje reprezentujñ bardzo silny rodzaj powiñzaþ pomiödzy klasami — jedna klasa za-
wiera drugñ. Kompozycje majñ zastosowanie w wyraĔaniu zwiñzków typu caäoĈè-czöĈè.
„CzöĈè” moĔe byè zaangaĔowana tylko w jeden zwiñzek tego typu w danym czasie. Czasy
Ĕycia instancji biorñcych udziaä w takim zwiñzku sñ prawie zawsze ze sobñ powiñzane. JeĔeli
wiöksza z nich, zawierajñca mniejszñ, zostanie zniszczona, to prawie zawsze pociñga to za
sobñ zniszczenie tej mniejszej. UML daje moĔliwoĈè przypisania czöĈci do innego wäaĈciciela przed
zniszczeniem, co pozwala jej nadal istnieè, ale jest to raczej sytuacja wyjñtkowa, a nie reguäa.
Kompozycje z reguäy czyta siö nastöpujñco: „…jest czöĈciñ…”. Oznacza to, Ĕe odczytywanie
kompozycji naleĔy zaczynaè od czöĈci do caäoĈci. Na przykäad jeĔeli dojdziemy do wniosku,
Ĕe okno w naszym systemie musi mieè pasek tytuäu, to moĔe go reprezentowaè klasa o nazwie
PasekTytuĪu
, która jest czöĈciñ klasy o nazwie
Okno
.
Kompozycje oznacza siö, stawiajñc wypeänionñ figurö diamentu obok klasy zawierajñcej oraz za
pomocñ linii ciñgäej wskazujñcej klasö, którñ ta klasa posiada. Na rysunku 2.27 przedstawiono
zwiñzek kompozycyjny pomiödzy klasñ o nazwie
Okno
a tñ o nazwie
PasekTytuĪu
.
Rysunek 2.27. PasekTytuäu jest czöĈciñ okna
Jako Ĕe jest to zwiñzek asocjacyjny, na linii kompozycyjnej moĔna umieszczaè informacje
dotyczñce komunikacyjnoĈci i licznoĈci. Patrz podrozdziaä „Asocjacje”.
Generalizacje
Generalizacja implikuje, Ĕe cel zwiñzku to bardziej ogólna (lub mniej konkretna) wersja klasy
Ēródäowej lub interfejsu. Generalizacje sñ czösto uĔywane do wyciñgania wspólnych cech
róĔnych klasyfikatorów. Na przykäad jeĔeli mielibyĈmy klasö o nazwie
Kot
i klasö o nazwie
Pies
, to moglibyĈmy utworzyè ich generalizacjö o nazwie
ZwierzĂ
. Peäna analiza problemu,
jak i kiedy stosowaè generalizacje (w szczególnoĈci w porównaniu z realizacjñ interfejsu),
mogäaby byè tematem ksiñĔki o zorientowanej obiektowo analizie i projektowaniu obiekto-
wym i nie bödziemy siö tym zajmowaè.
Generalizacje zazwyczaj odczytuje siö nastöpujñco: „…to…”. Czytanie naleĔy zaczñè od klasy
o wöĔszym znaczeniu. Wracajñc do przykäadu z psem i kotem, moglibyĈmy powiedzieè:
Kot
to
ZwierzĂ
.
Powiézania
_
43
Generalizacje oznacza siö za pomocñ linii ciñgäej zakoþczonej pustñ strzaäkñ wskazujñcñ
w kierunku klasy bardziej ogólnej. Na rysunku 2.28 przedstawiono powiñzanie
Kot
-
ZwierzĂ
.
Rysunek 2.28. Kot jest bardziej konkretnñ wersjñ klasy Zwierzö
W przeciwieþstwie do asocjacji generalizacje z reguäy nie majñ nazw ani Ĕadnego rodzaju
licznoĈci. UML pozwala na wielodziedziczenie, co oznacza, Ĕe klasa moĔe mieè wiöcej gene-
ralizacji niĔ jednñ, z których kaĔda reprezentuje pewien aspekt klasy potomnej. JednakĔe
niektóre nowoczesne jözyki programowania (np. Java i C#) nie obsäugujñ wielodziedziczenia,
oferujñc w zamian interfejsy i ich realizacje.
Klasy asocjacyjne
Czösto zwiñzek pomiödzy dwiema klasami nie jest prostñ strukturñ. Na przykäad zawodnik
piäkarski moĔe byè powiñzany z ligñ poprzez fakt bycia czäonkiem druĔyny. JeĔeli zwiñzki
pomiödzy dwoma elementami sñ bardzo zäoĔone, to moĔna je zaprezentowaè za pomocñ
tzw. klas asocjacyjnych. Klasa asocjacyjna ma nazwö i atrybuty jak normalna klasa. Prezentuje
siö jñ w taki sam sposób jak inne klasy, äñczñc jñ z reprezentowanñ przez niñ asocjacjñ za po-
mocñ linii przerywanej. Rysunek 2.29 przedstawia powiñzania zawodnika piäkarskiego z ligñ.
Rysunek 2.29. Przykäadowa klasa asocjacyjna
44
_
Rozdziaĥ 2. Diagramy klas
W kodzie Ēródäowym powiñzania z klasñ asocjacyjnñ zazwyczaj dajñ trzy klasy: po jednej dla
kaĔdej strony asocjacji oraz jednñ dla samej asocjacji. Pomiödzy przeciwnymi stronami aso-
cjacji moĔe byè bezpoĈrednie poäñczenie, ale nie musi. Implementacja moĔe wymagaè, aby
w celu dotarcia do klasy znajdujñcej siö po przeciwnej stronie trzeba byäo przejĈè przez klasö
asocjacyjnñ. Mówiñc inaczej,
Zawodnik
moĔe nie mieè bezpoĈredniego poäñczenia z ligñ, ale
z druĔynñ, która z kolei ma poäñczenie z ligñ. Konstrukcja powiñzaþ zaleĔna jest od konkretnej
implementacji. Nie zmienia siö tylko podstawowe pojöcie klasy asocjacyjnej.
Kwalifikatory asocjacyjne
Powiñzania pomiödzy elementami czösto opatrzone sñ róĔnymi säowami kluczowymi lub in-
nymi wartoĈciami. Na przykäad staäy klient banku moĔe byè rozpoznawany po numerze
konta, a päatnik podatku po numerze ubezpieczenia spoäecznego. Do przedstawiania takich
informacji w UML-u säuĔñ kwalifikatory asocjacji. Kwalifikator z reguäy jest atrybutem elementu
docelowego, aczkolwiek nie jest to wymóg. Ma on postaè niewielkiego prostokñta umiesz-
czonego pomiödzy asocjacjñ a elementem Ēródäowym. Nazwö kwalifikatora (zazwyczaj jest
to nazwa atrybutu) wpisuje siö w reprezentujñcym go prostokñcie. Rysunek 2.30 przedstawia
zwiñzek pomiödzy urzödem skarbowym a podatnikiem, z kwalifikatorem w postaci numeru
identyfikacji podatkowej podatnika.
Rysunek 2.30. Kwalifikator asocjacyjny
Warto zauwaĔyè, Ĕe licznoĈè pomiödzy kwalifikatorem asocjacji a podatnikiem wynosi 1.
OczywiĈcie urzñd skarbowy ma powiñzania z wieloma podatnikami, ale uĔycie kwalifikatora
wskazuje na fakt, Ĕe
NIP
w sposób jednoznaczny identyfikuje podatnika w
US
.
Interfejsy
Interfejs jest rodzajem klasyfikatora, który zawiera deklaracje wäaĈciwoĈci i metod, ale nie im-
plementuje ich. Interfejsy moĔna stosowaè do grupowania wspólnych elementów klasyfika-
torów w celu dostarczenia kontraktu, którego warunków musi dotrzymaè klasyfikator im-
plementujñcy te interfejsy. MoĔna na przykäad utworzyè interfejs o nazwie
Sortowalny
zawierajñcy jednñ operacjö o nazwie
wystĂpujePrzed(...)
. KaĔda klasa realizujñca interfejs
Sortowalny
musi implementowaè operacjö
wystĂpujePrzed(...)
.
Interfejsy
_
45
Niektóre nowoczesne jözyki programowania, np. C++, nie obsäugujñ interfejsów. Interfejsy
UML-a z reguäy sñ reprezentowane w postaci klas czysto abstrakcyjnych. Inne jözyki, takie
jak Java, obsäugujñ interfejsy, ale nie pozwalajñ na definiowanie ich wäaĈciwoĈci. W zwiñzku
z tym nasuwa siö wniosek, Ĕe zawsze w trakcie tworzenia modelu systemu naleĔy pamiötaè
o sposobie jego przyszäej implementacji.
Interfejs moĔna przedstawiè na jeden z dwóch sposobów. Wybór jednego z nich powinien
byè oparty na tym, co próbujemy pokazaè. Pierwszy sposób wykorzystuje standardowñ no-
tacjö klasyfikatorów UML-a przy uĔyciu stereotypu
«interface»
. Rysunek 2.31 przedstawia
interfejs
Sortowalny
.
Rysunek 2.31. Interfejs Sortowalny
Drugi sposób to notacja typu wtyczka-gniazdo. Reprezentacja ta pokazuje mniej szczegóäów
dotyczñcych interfejsu, ale lepiej nadaje siö do ukazywania powiñzaþ z klasami. Interfejs re-
prezentowany jest przez symbol kóäka, pod którym znajduje siö jego nazwa. Klasy zaleĔne
od tego interfejsu doäñczone sñ do odpowiadajñcego mu gniazda. Na rysunku 2.32 przedsta-
wiono interfejs
Sortowalny
za pomocñ notacji wtyczka-gniazdo.
Rysunek 2.32. Przykäady dostarczania i Ĕñdania interfejsów
Ze wzglödu na fakt, Ĕe interfejs okreĈla kontrakt tylko dla pewnego zestawu wäaĈciwoĈci, nie
moĔna utworzyè jego egzemplarza bezpoĈrednio. W zamian mówi siö, Ĕe klasa realizuje inter-
fejs, jeĔeli implementuje operacje i wäaĈciwoĈci. Realizacjö sygnalizuje siö poprzez zastoso-
wanie przerywanej linii, która bierze poczñtek w klasyfikatorze realizujñcym i prowadzi do
interfejsu oraz jest zakoþczona pustñ strzaäkñ. Klasy zaleĔne od interfejsu prezentowane sñ
przy uĔyciu linii przerywanej z pustñ strzaäkñ (zaleĔnoĈè). Rysunek 2.33 przedstawia klasö
realizujñcñ interfejs
Sortowalny
oraz zaleĔnñ od niego klasö.
46
_
Rozdziaĥ 2. Diagramy klas
Rysunek 2.33. Klasa Osoba realizuje interfejs Sortowalny, a klasa Sortowanie jest od niego zaleĔna
Implementacja operacji jest bardzo prosta — naleĔy dostarczyè implementacji na klasyfikato-
rze realizujñcym o takiej samej sygnaturze co operacja wykonywana na interfejsie. Z reguäy
z operacjñ, która musi byè honorowana przez jakñkolwiek implementacjö, zwiñzane sñ pewne
ograniczenia semantyczne. Realizacja wäaĈciwoĈci jest bardziej subtelna. WäaĈciwoĈè inter-
fejsu stanowi, Ĕe dowolna realizujñca go klasa musi w jakiĈ sposób przechowywaè dane
okreĈlone przez tö wäaĈciwoĈè. WäaĈciwoĈè interfejsu niekoniecznie oznacza, Ĕe dla kla-
syfikatora realizujñcego bödzie jakaĈ wäaĈciwoĈè skojarzona. Klasyfikator musi jednak mieè
moĔliwoĈè przechowywania danych reprezentowanych przez tö wäaĈciwoĈè i umoĔliwiaè
manipulowanie niñ.
Szablony
Podobnie jak interfejsy pozwalajñ na okreĈlenie obiektów, z jakimi dana klasa moĔe wcho-
dziè w interakcje, UML umoĔliwia tworzenie abstrakcji dla typu klas, z którymi moĔe komu-
nikowaè siö dana klasa. MoĔna na przykäad napisaè klasö o nazwie
Lista
przechowujñcñ
obiekty dowolnego typu (w C++ prawdopodobnie byäby to typ
void*
, a w Java i C#
Object
).
Jednak pomimo Ĕe chcemy, aby nasza klasa byäa w stanie obsäuĔyè obiekty dowolnego typu,
chcemy równieĔ, aby wszystkie obiekty danej listy reprezentowaäy jeden typ. Tego rodzaju
abstrakcje w UML-u moĔna tworzyè za pomocñ szablonów.
Aby zaznaczyè, Ĕe klasa jest szablonem (lub jest sparametryzowana), naleĔy w jej górnym
prawym rogu narysowaè prostokñt, którego boki sñ liniñ przerywanñ. Dla kaĔdego elementu,
z którego chcemy zrobiè szablon, naleĔy podaè nazwö stanowiñcñ znak zastöpczy dla wäa-
Ĉciwego typu. Nazwö tego znaku naleĔy wpisaè w narysowanym prostokñcie. Na rysunku 2.34
przedstawiono klasö
Lista
mogñcñ obsäuĔyè dowolny typ.
Szablony
_
47
Rysunek 2.34. Klasa szablonowa Lista
W powyĔszym przykäadzie dla jasnoĈci uĔyto nazwy TypElementu dla typu sza-
blonowego. W praktyce czösto pisze siö w skrócie tylko T.
W obröbie klasy moĔna mieè wiele typów szablonowych. Ich nazwy naleĔy wtedy rozdzieliè
przecinkami. W razie potrzeby naäoĔenia ograniczeþ co do typów, które uĔytkownik moĔe
podmieniè, naleĔy zastosowaè dwukropek, a po nim wstawiè nazwö typu. Rysunek 2.35
przedstawia bardziej skomplikowanñ wersjö klasy
Lista
, która wymaga sortera razem z typem
obiektu, który ma byè przechowywany na liĈcie.
Rysunek 2.35. Klasa szablonowa z ograniczeniami dotyczñcymi typów
Definiowanie ograniczeþ dla typów, które mogñ zostaè uĔyte, jest z funkcjonalnego punktu
widzenia podobne do definiowania interfejsu dla skäadowej bödñcej szablonem. Wyjñtkiem
jest to, Ĕe uĔytkownik moĔe mieè moĔliwoĈè dalszego ograniczania egzemplarza naszej klasy
poprzez zdefiniowanie podklasy naszego typu.
Tworzñc egzemplarz klasy
Lista
, uĔytkownik musi podaè rzeczywisty typ, który ma byè za-
stosowany w miejsce
TypElementu
. Nazywa siö to wiñzaniem typu z szablonem. Wiñzanie
oznacza siö za pomocñ säowa kluczowego
«bind»
, po którym nastöpuje okreĈlenie typu przy
uĔyciu nastöpujñcej skäadni:
< TypSzablonowy -> RzeczywistyTyp >
Skäadniö wiñzania moĔna stosowaè wszödzie tam, gdzie odnosimy siö do klasy szablonowej
w celu zaznaczenia, Ĕe chcemy uĔyè wiñzanej wersji tej klasy. Nazywa siö to wiñzaniem jawnym.
Na przykäad rysunek 2.36 przedstawia podklasö klasy
Lista
o nazwie
ListaPracowników
,
która wiñĔe
TypElementu
klasy
List
z klasñ o nazwie
Pracownik
.
Säowo kluczowe
bind
informuje równieĔ, jakie typy powinny zostaè uĔyte z egzemplarzem
szablonu. Nazywa siö to wiñzaniem niejawnym i zostaäo przedstawione na rysunku 2.37.
48
_
Rozdziaĥ 2. Diagramy klas
Rysunek 2.36. Jawne wiñzanie szablonu
Rysunek 2.37. Niejawne wiñzanie szablonu
Różne wersje diagramów klas
Ze wzglödu na fakt, Ĕe diagramy klas Ĉwietnie nadajñ siö do modelowania struktur, znajdujñ
zastosowanie w obrazowaniu dobrze zdefiniowanych, hierarchicznych informacji. Z pewnym
powodzeniem uĔywa siö ich do obrazowania schematów XML i bazodanowych. Aby
wszystko byäo jasne: osoby zajmujñce siö schematami XML i bazodanowymi na co dzieþ majñ
pewne wñtpliwoĈci co do uĔywania diagramów klas do obrazowania tego typu informacji.
Konkretnie chodzi im o to, Ĕe diagramy te sñ zbyt ogólne. KaĔda domena ma wäasnñ notacjö,
która moĔe lepiej siö nadawaè do przedstawienia skomplikowanych powiñzaþ lub informacji
wäaĈciwych danej domenie. UML ma jednak tö zaletö, Ĕe jest wspólnym jözykiem rozumianym
takĔe przez osoby spoza branĔy XML-a i baz danych.
Schematy XML
Strukturö dokumentu XML moĔna przedstawiè za pomocñ schematu XML. Schematy XML sñ
dla dokumentów XML tym, czym klasy dla obiektów. Dokumenty XML sñ egzemplarzami
schematów XML. W zwiñzku z tym nietrudno sobie zdaè sprawö, Ĕe diagramy klas moĔna
stosowaè do modelowania schematów XML. Schematy te opisywane sñ za pomocñ jözyka
XSDL (XML Structure Definition Language). XSDL jest jözykiem tekstowym (w przeciwieþstwie
do graficznego UML-a), a jego zastosowania mogñ byè wszechstronne. Odwzorowanie XSDL-a
w UML-u moĔe uäatwiè odczyt schematu.
Różne wersje diagramów klas
_
49
Podstawowymi elementami XSDL sñ elementy XML poäñczone w sekwencje, wybory i struktu-
ry zäoĔone. Do kaĔdego elementu mogñ byè doäñczone dodatkowe informacje w postaci atry-
butów (co jest dosyè wygodne). Tworzñcy modele z reguäy reprezentujñ elementy XML jako
klasy UML-a, a atrybuty XSDL jako atrybuty UML-a. KaĔdy element jest poäñczony z nastöp-
nym za pomocñ strzaäek kompozycji. WartoĈci dotyczñce licznoĈci podawane dla tych po-
wiñzaþ okreĈlajñ, ile razy jeden element pojawia siö w innym. Listing 2.1 przedstawia przy-
käadowy dokument XML opisujñcy element wyposaĔenia.
Listing 2.1. Przykäadowy dokument XML
<?xml version="1.0" encoding="UTF-8"?>
<equipmentlist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="equipment.xsd">
<equipment equipmentid="H-1">
<shortname>
<langstring lang="en">Hammer</langstring>
</shortname>
<technicalcontact>
<contact>
<name>Ron</name>
<telephone>555-1212</telephone>
</contact>
</technicalcontact>
<trainingcontact>
<contact>
<name>Joe</name>
<email>joe@home.com</email>
</contact>
</trainingcontact>
</equipment>
</equipmentlist>
Listing 2.2 przedstawia kod XSDL opisujñcy powyĔszy dokument XML.
Listing 2.2. Schemat XML opisujñcy dokument XML z listingu 2.1
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!-- ~Class: contact ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="contact" type="contact"/>
<xs:complexType name="contact">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:choice>
<xs:element name="telephone" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<!-- ~Class: equipment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="equipment" type="equipment"/>
<xs:complexType name="equipment">
<xs:sequence>
<xs:element ref="shortname"/>
<xs:element name="technicalcontact" type="technicalcontact"/>
<xs:element name="trainingcontact" type="trainingcontact"/>
</xs:sequence>
50
_
Rozdziaĥ 2. Diagramy klas
<xs:attribute name="equipmentid" type="xs:string" use="required"/>
</xs:complexType>
<!-- ~Class: equipmentlist ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="equipmentlist" type="equipmentlist"/>
<xs:complexType name="equipmentlist">
<xs:sequence>
<xs:element ref="equipment" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- ~Class: <<XSDtopLevelAttribute>> lang~~~~~~~~~~~~ -->
<xs:attribute name="lang" type="xs:language"/>
<!-- ~Class: langstring ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="langstring" type="langstring"/>
<xs:complexType name="langstring">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="en"/>
<xs:enumeration value="fr"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- ~Class: shortname ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="shortname" type="shortname"/>
<xs:complexType name="shortname">
<xs:sequence>
<xs:element ref="langstring" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- ~Class: technicalcontact ~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="technicalcontact" type="technicalcontact"/>
<xs:complexType name="technicalcontact">
<xs:sequence>
<xs:element ref="contact" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- ~Class: trainingcontact ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xs:element name="trainingcontact" type="trainingcontact"/>
<xs:complexType name="trainingcontact">
<xs:sequence>
<xs:element ref="contact" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Rysunek 2.38 przedstawia reprezentacjö UML-a powyĔszego schematu. Elementy reprezen-
towane sñ jako klasy, z jednym wyjñtkiem: definicja
kontakt
zawiera opcjö
wybór
. Rysunek 2.38
obrazuje to za pomocñ innej klasy zaklasyfikowanej jako
XSDWybór
. Opcje zostaäy zaprezen-
towane jako atrybuty klasy.