Bartosz Walter Prowadzący: Bartosz Walter UML cz. I Prowadzący: Bartosz Walter UML cz. I
Zasady skutecznego działania Specyfikacja wymagań (przypadki użycia) Bartosz Walter Plan wykładów Zasady skutecznego działania Specyfikacja wymagań (przypadki użycia) Przeglądy artefaktów (inspekcje Fagana) Język UML, cz. I Język UML, cz. II Metody formalne (sieci Petriego) Wzorce projektowe Zarządzanie konfiguracją (CVS) Wprowadzenie do testowania Automatyzacja wykonywania testów (jUnit) Programowanie Ekstremalne Ewolucja oprogramowania i refaktoryzacja Wykład jest pierwszym z dwóch, poświęconych językowi modelowania UML. Stanowi kontynuację cyklu wykładów poświęconych inżynierii oprogramowania. UML cz. I
Modelowanie funkcjonalności Diagram klas Diagram obiektów Przykład Bartosz Walter Agenda Historia i geneza UMLa Koncepcja modeli UML Modelowanie funkcjonalności Diagram klas Diagram obiektów Przykład Podczas bieżącego wykładu zostanie przedstawione wprowadzenie do języka UML, jego geneza oraz koncepcja perspektyw modelowania. Omówione będą także dwie perspektywy języka: przypadków użycia oraz logiczna (struktury statycznej). UML cz. I
Bartosz Walter Historia UML OOPSLA 1995: wersja 0.8 Metody Zunifikowanej (Booch & Rumbaugh, Rational Software), dołącza Jacobson UML 1.3 UML 2.1 (plan) włączenie się do prac OMG niezależne notacje modelowania: Booch, Coad/Yourdon, OMT, OOSE, Fusion UML 1.5 UML 1.0 (Rational Software) i UML 1.1 (OMG) UML 2.0 W latach 80-tych i na początku lat 90-tych istniało na rynku wiele notacji i metodyk modelowania, stosujących podobne rozwiązania i elementy o zbliżonej semantyce (np. klasy), ale całkowicie różniące się sposobem ich reprezentacji. Niektóre z nich z nich zdobyły większą popularność (np. OOAD, OOSE, OMT, Fusion, metoda Shlaera-Mellora czy Coada-Yourdona), jednak nadal brak było jednego rozwiązania czy jednego standardu, który zaspokajałby wszystkie potrzeby, a jednocześnie posiadałby dominującą pozycję, wokół którego mogłaby postępować standaryzacja. W większości były to notacje niekompletne, obejmujące jedynie wybrane aspekty modelowania, i nie definiujące szczegółowo wielu pojęć. Dlatego, na początku lat 90-tych G. Booch (twórca metody OOAD, kładącej nacisk na kwestie projektowania i implementacji) i J. Rumaugh (autor metody OMT, skupiającej się na modelowaniu dziedziny przedmiotowej), pracujący dla firmy Rational Software (dzisiaj Rational jest własnością IBMa) dostrzegli możliwość wzajemnego uzupełnienia swoich metod i rozpoczęli prace nad Metodą Zunifikowaną (ang. Unified Method), która miała połączyć najlepsze cechy dwóch, dotychczas niezależnych, notacji. Na konferencji OOPSLA w 1995 roku zaprezentowali oni wersję 0.8 Metody Zunifikowanej, a krótko potem dołączył do nich inny znany metodolog - I. Jacobson (twórca metody OOSE, zorientowanej na modelowanie funkcjonalności, użytkowników i cyklu życia produktu). W ten sposób powstała "masa krytyczna" wielkich i uznanych nazwisk, która dawała szansę na opanowanie rynku przez nowopowstałą metodę. W roku 1996 do prac włączyła się niezależna organizacja OMG (Object Management Group), której udział dawał szansę na wpływ na kształtowanie powstającego języka UML także innym firmom, nie tylko Rational Software. Efektem prac była najpierw wersja 1.0 UML opublikowana przez Rational, a kilka miesięcy później – wersja 1.1, wydana już pod egidą OMG. Kolejne wersje pojawiały się w odstępach kilkuletnich, pozwalając na stosowanie nowych diagramów, uspójniając notację i umożliwiając na modelowanie nowych dziedzin. Najnowsza wersja UML to 2.0. Wraz z rozwojem UML zdobył dominującą pozycję na rynku – poza nim istnieją na nim jedynie notacje związane z narzędziami 4GL. ok.1990 1995 1996 1997 2000 2003 2004 2006 UML cz. I
Trzej amigos G. Booch I. Jacobson J. Rumbaugh OMT przypadki użycia Bartosz Walter Trzej amigos G. Booch I. Jacobson J. Rumbaugh OMT Trzej autorzy UMLa: G. Booch, I. Jacobson i J. Rumbaugh zunifikowali swoje notacje, tworząc jedną metodę. Z poszczególnych notacji przejęto najlepsze rozwiązania: z metody Boocha przejęto techniki projektowania i implementacji, z metody Jacobsoba – modelowanie wymagań w postaci przypadków użycia, a z metody Rumbaugha – modelowanie dziedzinowe. przypadki użycia metoda Boocha UML cz. I
Czym jest UML? metodyką narzędziem notacją graficzną UML nie jest Bartosz Walter Czym jest UML? metodyką UML nie określa metody modelowania zaleca jedynie stosowanie podejścia przyrostowego narzędziem UML to specyfikacja dla narzędzi notacją graficzną UML określa sposób zapisu modeli językiem programowania generowanie kodu z modelu stosowane obecnie na niewielką skalę Wokół UML krąży wiele prawdziwych i nieprawdziwych informacji dotyczących jego przeznaczenia i obszaru zastosowań. Warto zatem podkreślić, że UML jest przede wszystkim językiem modelowania, z określoną notacją graficzną i semantyką poszczególnych symboli. W znacznie mniejszym stopniu jest to język programowania (mimo prowadzonych badań nad użyciem UML jako formalnej specyfikacji służącej do generowania kodu wykonywalnego lub przynajmniej jego szablonu). UML nie jest natomiast, wbrew popularnym opiniom, metodyką modelowania, ponieważ nie określa, w jaki sposób należy modelować systemy (choć zwykle jest stosowany w przyrostowym cyklu rozwojowym oprogramowania, np. zgodnym z RUP), ani narzędziem – ponieważ UML jest jedynie specyfikacją języka. UML nie jest UML jest UML cz. I
Konstrukcja UML UML składa się z dwóch podstawowych elementów: notacja Bartosz Walter Konstrukcja UML UML składa się z dwóch podstawowych elementów: notacja elementy graficzne składnia języka modelowania istotna przy szkicowaniu modeli metamodel definicje pojęć języka i powiązania pomiędzy nimi istotny przy graficznym programowaniu UML jako język posiada dwie podstawowe składowe: notację graficzną, określającą wygląd poszczególnych elementów używanych na diagramach, oraz ich semantykę, czyli tzw. metamodel, wyrażony także – rzecz jasna – przy użyciu UML. Z punktu widzenia analityka istotniejsze jest czytelne i jednoznaczne opisanie modelu w taki sposób, aby inne osoby mogły zrozumieć jego sens. Zatem ważniejsza dla niego jest notacja, zaś metamodel powinien być jedynie intuicyjnie (a więc niekoniecznie formalnie) zrozumiały. Z kolei przy generowaniu kodu i przejściu do implementacji ważniejsze jest ścisłe rozumienie znaczenia poszczególnych elementów, tak, aby możliwa była automatyczna konwersja modelu np. do kodu programu. W tym przypadku nacisk kładzie się na metamodel. Z punktu widzenia modelowania ważniejsza jest notacja. Z punktu widzenia generacji kodu – metamodel. UML cz. I
Perspektywy 4+1 Model Implementacyjna Logiczna Przypadków użycia Bartosz Walter Perspektywy 4+1 Implementacyjna Logiczna Przypadków użycia Model Wdrożenia Modelowanie złożonych systemów jest zadaniem trudnym i angażuje wiele osób o różnym sposobie postrzegania systemu. Aby uwzględnić te punktu widzenia, UML jest często określany jako język modelowania posiadający 4+1 perspektyw. Cztery pierwsze opisują wewnętrzną strukturę programu na różnych poziomach abstrakcji i szczegółowości. Ostatnia perspektywa (+1) opisuje funkcjonalność systemu widzianą przez jego użytkowników. Są to następujące perspektywy: Perspektywa przypadków użycia – opisuje funkcjonalność, jakiej od systemu oczekują jego przyszli użytkownicy (a więc mówi co powinien wykonywać system) Perspektywa logiczna – zawiera opis sposobu realizacji funkcjonalności, strukturę systemu widzianą przez projektanta (skupia się więc na opisie jak funkcjonalność ma być realizowana) Perspektywa implementacyjna – opisuje szczegółowo poszczególne moduły i ich interfejsy wraz z zależnościami, z określeniem ograniczeń wynikających z zastosowanego języka programowania, wybranych technologii etc.; perspektywa ta jest przeznaczona dla programisty Perspektywa procesowa – zawiera podział systemu na procesy (czynności) i procesory (jednostki wykonawcze); opisuje właściwości pozafunkcjonalne systemu i służy przede także programistom i integratorom Perspektywa wdrożenia – definiuje fizyczny podział elementów systemu i sposób ich rozmieszczenia w infrastrukturze; perspektywa taka służy integratorom i instalatorom systemu Każda perspektywa korzysta z własnego zestawu diagramów pozwalających czytelnie przedstawić modelowane zagadnienie. Procesowa UML cz. I
Diagramy UML UML obejmuje 13 rodzajów diagramów: diagram pakietów Bartosz Walter Diagramy UML UML obejmuje 13 rodzajów diagramów: diagram pakietów diagram klas i diagram obiektów diagram struktur złożonych diagram komponentów diagram wdrożenia diagram przypadków użycia diagram czynności diagram maszyny stanowej diagramy interakcji (sekwencji, komunikacji, przeglądu interakcji) diagram uwarunkowań czasowych modelowanie strukturalne modelowanie behawioralne W UML zdefiniowano 13 rodzajów diagramów, które można z grubsza podzielić na dwie główne grupy: opisujących strukturę systemu i opisujących jego zachowanie. Naturalnie, nie wszystkie są i muszą być używane jednocześnie – wybór zależy od rodzaju i złożoności modelowanego systemu. Niektóre z nich dotyczą tego samego aspektu modelowania ujętego nieco inaczej, z uwypukleniem jednych i pominięciem innych elementów, dlatego dobór rodzajów diagramów zależy także od preferencji analityka. UML cz. I
Diagram przypadków użycia Bartosz Walter Diagram przypadków użycia Diagram przypadków użycia definiuje granice modelowanego systemu określa jego kontekst wymienia użytkowników systemu i jednostki zewnętrzne przedstawia funkcje dostępne dla użytkowników określa powiązania i zależności pomiędzy nimi Pierwszym diagramem języka UML jest diagram przypadków użycia (ang. use-case diagram). Służy on do modelowania aktorów (użytkowników systemu, odbiorców efektów pracy systemu, systemów zewnętrznych) i ich potrzeb w stosunku do tworzonego systemu. Przypadki użycia prezentowane na tym diagramie to sekwencje czynności, które prowadzą do spełnienia celu przypadku użycia (zaspokojenia pewnej potrzeby użytkownika). Przypadki użycia mogą być między sobą powiązane za pomocą kilku rodzajów relacji, dzięki czemu diagram ten określa poszczególne funkcje systemu i ich zależności. UML cz. I
Aktor Aktor inicjuje wykonanie funkcji systemu Bartosz Walter Aktor Aktor inicjuje wykonanie funkcji systemu wymaga dostępu do systemu reprezentuje punkt widzenia na system jest osobą fizyczną, rolą w systemie lub systemem zewnętrznym Bibliotekarz Czytelnik Zegar Aktor na diagramie przypadków użycia jest osobą (lub dowolną inną jednostką), która w jakiś sposób wymienia informacje z systemem, choć pozostaje poza jego zakresem. Jest więc w szerokim znaczeniu użytkownikiem tego systemu, tzn. żąda od systemu wykonania pewnych funkcji i/lub odbiera efekty ich wykonania. Aktor opisuje rolę, a nie konkretną osobę lub jednostkę (a więc aktorem jest np. Kierowca, a nie Jan Nowak, który faktycznie jest kierowcą). Aktorzy mogą być powiązani ze sobą relacją uogólnienia/uszczegółowienia: w ten sposób zachowanie bardziej ogólnego aktora jest dziedziczone przez aktora bardziej szczegółowego. Ponadto są powiązani z przypadkami użycia, z których korzystają. Aktor jest reprezentowany na diagramie przypadków użycia w różnoraki sposób: jako sylwetka z nazwą aktora, jako prostokąt ze słowem kluczowym «actor» lub z ikoną. Przykładami aktorów w systemie bibliotecznym mogą być Bibliotekarz i Czytelnik, reprezentujący fizyczne osoby korzystające z tego systemu, ale także Zegar, który cyklicznie wysyła komunikat powodujący wyszukanie w katalogu książek o przekroczonym terminie zwrotu. UML cz. I
Bartosz Walter Przypadek użycia rozszerzanie zawieranie Przypadek użycia reprezentuje kompletną funkcję dostępną dla aktora. Przypadki użycia mogą być powiązane zależnościami: Uszczegółowienie: specjalizowana wersja przypadku użycia Rozszerzanie: dodatkowa funkcjonalność przypadku użycia Zawieranie: wykonanie jednego przypadku użycia przez drugi Wyszukanie Powiadomienie Czytelnik <<include>> <<extend>> uszczegółowienie Rezerwacja Przypadek użycia reprezentuje zamkniętą i kompletną funkcjonalność dostępną dla aktora. Zgodnie z definicją, przypadek użycia w UML jest zdefiniowany jako zbiór akcji wykonywanych przez system, które powodują efekt zauważalny dla aktora. Przypadki użycia zawsze muszą być inicjowane (bezpośrednio lub przez zależności) przez aktora i wykonywane w jego imieniu. Ponadto, przypadek użycia musi dostarczać pewną wartość użytkownikowi oraz musi być kompletny, to znaczy w pełni realizować podaną funkcjonalność oraz dostarczać wyniki aktorowi. Przypadki użycia komunikują się z aktorami poprzez powiązania, pokazujące, który aktor ma dostęp do podanego przypadku użycia. Ponadto mogą być powiązane pomiędzy sobą: relacją uogólnienia, rozszerzenia i zawierania. Rezerwacja czasopisma Rezerwacja książki UML cz. I
Przykład Przedłużenie Zwrot Wypożyczenie do czytelni Wypożyczenie Bartosz Walter Przykład Przedłużenie Zwrot Wypożyczenie do czytelni Wypożyczenie Rezerwacja czasopisma Rezerwacja książki Rezerwacja Bibliotekarz Rejestracja czytelnika Czytelnik Wyszukanie <<include>> Zegar Powiadomienie <<extend>> Przykład przedstawia diagram przypadków użycia. Występuje w nim trzech aktorów: Czytelnik, Bibliotekarz i Zegar. Pierwsi dwaj reprezentują role użytkowników systemu, natomiast Zegar służy do generowania cyklicznych powiadomień. Czytelnik i Bibliotekarz są aktorami korzystającymi z przypadków użycia (tzn. inicjują je i są odbiorcami efektów ich wykonania). Niektóre z nich, np. Zwrot lub Wypożyczenie do czytelni, są przez nich współdzielone, natomiast Rejestracja czytelnika i Przedłużenie są dostępne tylko dla jednego albo drugiego aktora. Przypadek użycia Wyszukanie jest włączony do kilku innych przypadków użycia: Rezerwacji, Wypożyczenia i Wypożyczenia do czytelni. W ten sposób jest on wywoływany w sposób pośredni przez aktora, a bezpośrednio przez inny przypadek użycia. Przypadek użycia Rezerwacja jest rozszerzany przez Powiadomienie. Oznacza to, że Powiadomienie może uczestniczyć w realizacji funkcji Rezerwacji. Ponadto Rezerwacja posiada dwa szczegółowe przypadki: Rezerwację książki i Rezerwację czasopisma. UML cz. I
Bartosz Walter Diagram klas Diagram klas przedstawia klasy występujące w systemie i statyczne relacje pomiędzy nimi wraz z ograniczeniami. Jest podstawowym diagramem struktury logicznej systemu. Diagram klas (ang. class diagram) jest najczęściej stosowanym diagramem UML. Z reguły zawiera także największą ilość informacji i stosuje największą liczbę symboli. Na diagramie są prezentowane klasy, ich atrybuty i operacje, oraz powiązania między klasami. Diagram klas przedstawia więc podział odpowiedzialności pomiędzy klasy systemu i rodzaj wymienianych pomiędzy nimi komunikatów. Z uwagi na rodzaj i ilość zawartych na tym diagramie danych jest on najczęściej stosowany do generowania kodu na podstawie modelu. UML cz. I
Klasa i obiekt nazwa atrybuty operacje Bartosz Walter UML cz. I Klasa jest reprezentowana przez prostokąt z wydzielonymi przedziałami: nazwą, atrybutami i operacjami. W celu zwiększenia czytelności, dowolny z nich można ukryć bądź też dodać nowy (np. przechowujący zdarzenia lub wyjątki), choć w większości przypadków klasa zawiera właśnie trzy przedziały. Tradycyjnie nazwa klasy zaczyna się z dużej litery, jest wytłuszczona, a w przypadku klasy abstrakcyjnej – także zapisana czcionką pochyłą. Obiekt, oznaczany identycznym symbolem graficznym, jest, podobnie jak w przypadku programowania obiektowego, instancją klasy. Nazwa obiektu jest umieszczana przed nazwą klasy i oddzielana od niej dwukropkiem, np: Jan Nowak : Czytelnik. Cechy klasy reprezentują informację, jaką klasa przechowuje. Mogą zostać zapisane w postaci dwóch, w zasadzie równoważnych notacji: jako atrybuty klasy (umieszczane w przedziale atrybutów) lub jako relacje pomiędzy klasami (zapisywane w postaci linii łączącej klasy – będzie o tym mowa nieco później). Zwykle pierwsza notacja jest stosowana do typów prostych lub obiektów reprezentujących wartości (np. imię, data urodzenia), natomiast druga do typów złożonych (np. uprawnienia, lista wypożyczonych książek). Ostatni przedział zawiera listę operacji dostępnych w danej klasie. Operacje reprezentują usługi, jakie klasa oferuje na rzecz innych obiektów. Realizacje operacji – metody – dostarczają implementacji tych usług. operacje UML cz. I
widoczność nazwa : typ[krotność] {ograniczenia} = wartość dom. Bartosz Walter Atrybuty klasy Cechy klasy są zapisywane w postaci atrybutów klasy lub asocjacji z innymi klasami. Atrybuty reprezentują wartości proste lub niewielkie obiekty, asocjacje – obiekty złożone widoczność nazwa : typ[krotność] {ograniczenia} = wartość dom. Skąd atrybut jest widoczny? Jaka jest wartość atrybutu, gdy nie podano jej wprost? Ile obiektów trzeba i ile można umieścić w atrybucie? Zwykle atrybut jest opisywany tylko przez dwa elementy: nazwę i typ. Jednak pełna definicja może obejmować także inne jego właściwości: widoczność atrybutu, definiującą, z jakich miejsc systemu atrybut jest dostępny, krotność, która określa ile obiektów mieści się w atrybucie, dodatkowe ograniczenia nałożone na atrybut, i wartość domyślną. W celu uproszczenia zapisu elementom, którym w definicji atrybutu nie podano wartości, przypisywane są wartości domyślne (widoczność prywatna, krotność 1) lub są one pomijane. Jakie dodatkowe warunki spełniają wartości atrybutu? UML cz. I
Poziomy widoczności UML definiuje 4 poziomy widoczności cech i metod Bartosz Walter Poziomy widoczności UML definiuje 4 poziomy widoczności cech i metod + publiczny – element jest widoczny z każdego miejsca w systemie # chroniony – element jest widoczny we własnej klasie i jej podklasach – prywatny – element jest widoczny tylko we własnej klasie ~ publiczny wewnątrz pakietu – element jest widoczny tylko wewnątrz własnego pakietu Podobnie jak wiele wysokopoziomowych języków programowania, UML posiada 4 poziomy (zasięgi) widoczności: publiczny, chroniony, prywatny i publiczny wewnątrz pakietu. Poziomy te zwykle służą do opisywania widoczności cech (atrybutów i asocjacji) oraz operacji, jednak dotyczą także np. klas pakietów etc. Każdy poziom jest oznaczany tekstowym symbolem umieszczanym przed elementem, którego dotyczy: + (publiczny), # (chroniony), – (prywatny), ~ (publiczny wewnątrz pakietu). UML cz. I
Bartosz Walter Krotność Krotność pozwala określić minimalną i maksymalną liczbę obiektów, jakie można powiązać z daną cechą: dolna granica..górna granica – przedział od-do 1 – dokładnie jeden obiekt 0..1 – opcjonalnie jeden obiekt 1..* - przynajmniej jeden obiekt 1, 3, 5 – konkretne liczby obiektów * - dowolna liczba obiektów Krotność cechy (zarówno atrybutu, jak i relacji) wskazuje, ile obiektów można, a ile trzeba w niej zawrzeć. Krotność można określać jako ograniczenie dolne i górne, jednak oczywiste lub powtarzające się wartości graniczne można pomijać, np. zapis 0..* jest skracany do *, a zapis 1..1 do 1. W praktyce programowania istotna są wartości 0, 1 i *, natomiast wartości dyskretne są szczególnymi przypadkami wymienionych trzech. Dlatego w wersji 2.0 UML formalnie usunięto możliwość podawania konkretnych liczb będących ograniczeniami, np. 2..4, jednak z uwagi na czytelność tego zapisu użycie go nie stanowi wielkiego błędu. UML cz. I
Właściwości i ograniczenia atrybutów Bartosz Walter Właściwości i ograniczenia atrybutów Z atrybutem mogą być związane dodatkowe ograniczenia, które określają jego właściwości, np.: {ordered} – obiekty wewnątrz cechy są uporządkowane {unordered} – obiekty są nieuporządkowane {unique} – obiekty wewnątrz cechy nie powtarzają się {nonunique} – obiekty wewnątrz cechy mogą się powtarzać {frozen} – wartość atrybutu nie może być zmodyfikowana po jej przypisaniu Niemal każdy element w UML może posiadać dodatkowe właściwości i ograniczenia, które szczegółowo opisują jego zachowanie i przeznaczenie. Są one zapisywane w nawiasach klamrowych. Na przykład, atrybuty klasy można oznaczyć za pomocą ograniczenia {sorted}, co oznacza, że są one w jakiś sposób (zwykle rosnąco, leksykograficznie) posortowane. Ograniczenie {unique} wymaga, aby obiekty pamiętane wewnątrz cechy nie powtarzały się (tak, jak ma to miejsce wewnątrz zbioru). Właściwość {frozen} oznacza taką cechę, której wartość po zdefiniowaniu nie może być zmodyfikowana (a więc nie można dodać, usunąć czy zmienić obiektu należącego do tej wartości). UML cz. I
Bartosz Walter Atrybuty pochodne Atrybut pochodny (wywiedziony) może zostać obliczony na podstawie innych atrybutów. Atrybutów pochodnych nie trzeba implementować. Atrybuty pochodne (ang. derived) są zależne od innych atrybutów i ich wartości można obliczyć na podstawie tych atrybutów. Często w fazie implementacji są przekształcane w metody lub ich wartość jest obliczana na bieżąco. Oznacza to, że nie ma potrzeby ich bezpośredniego zapamiętywania w klasie. Atrybuty pochodne są oznaczane znakiem '/' umieszczonym przed nazwą atrybutu. przekroczone = (Data końca.Dni() – Data początku.Dni()) > MAX_WYPOŻYCZENIE UML cz. I
Bartosz Walter Składowe statyczne Składowe (atrybuty i operacje) statyczne są widoczne także wewnątrz klasy, nie tylko wewnątrz obiektów. Klasa Obiekt «instantiates» Składowe (a więc zarówno atrybuty, jak i metody) statyczne są związane nie z pojedynczą instancją (jak ma to miejsce w przypadku np. imion, nazwisk etc.), a z całą klasą i dotyczą wszystkich instancji tej klasy. Są zatem widoczne zarówno w klasie, jak i w jej instancji: odwołanie do nich nie wymaga istnienia instancji klasy, a jedynie podania nazwy klasy. Składowe statyczne klasy są oznaczane podkreśleniem jej sygnatury. W klasie widoczny tylko atrybut statyczny W obiekcie widoczne wszystkie atrybuty UML cz. I
widoczność nazwa(parametr1, parametr2,...) : typ {ograniczenia} Bartosz Walter Operacje Operacja to proces, który klasa potrafi wykonać. widoczność nazwa(parametr1, parametr2,...) : typ {ograniczenia} kierunek nazwa typ[krotność] = wartość dom. kierunki parametrów: in: wejściowy out: wyjściowy inout: wejściowo-wyjściowy return: zwracany z metody Operacje w klasie definiują jej funkcjonalność i stanowią informację dla innych obiektów, jakie komunikaty można do tej klasy wysłać. Operacje są opisywane w UMLu podobnie jak atrybuty, oczywiście, z uwzględnieniem listy parametrów i pominięciem wartości domyślnej. Parametry są zapisywane tak jak atrybuty klasy, jednak są poprzedzone informacją o kierunku przekazania wartości: in (parametr wejściowy), out (parametr wyjściowy), inout (parametr wejściowo-wyjściowy) i return (wartość zwracana z metody). Jeżeli kierunek nie został określony, wówczas przyjmuje się, że domyślnym kierunkiem jest wejściowy. UML cz. I
Właściwości i ograniczenia operacji Bartosz Walter Właściwości i ograniczenia operacji Operacje, podobnie jak atrybuty, mogą posiadać dodatkowe właściwości i ograniczenia: {query} – operacja nie modyfikuje stanu obiektu – jest zapytaniem «exception» – metoda może zgłaszać wyjątek Definicja operacji wewnątrz klasy przewiduje, podobnie jak w przypadku atrybutów, możliwość umieszczenia dodatkowych informacji i ograniczeń. Spośród nich największe znaczenie ma słowo kluczowe {query} oznaczające, że metoda jedynie zwraca fragment stanu obiektu, natomiast go nie modyfikuje (czyli nie ma efektu ubocznego w postaci np. modyfikacji stanu obiekty). Informacja taka ma bardzo duże znaczenie w fazie implementacji. Podobnie metoda może zgłaszać wyjątki. Wprawdzie UML nie definiuje sposobu, w jaki powinna być oznaczona taka metoda, jednak powszechnie stosowane jest słowo kluczowe exception wraz z nazwą wyjątku jako opis klasy wyjątku, oraz informacja o możliwości zgłoszenia wyjątku skojarzona z metodą. UML cz. I
Warunki wstępne i końcowe Bartosz Walter Warunki wstępne i końcowe Warunki wstępne opisują stan systemu wymagany przed wykonaniem operacji Warunki końcowe gwarancje dotyczące stanu systemu po wykonaniu operacji wyszukaj(tytuł: String) : Wydawnictwo[] pre: tytuł != null Operację można także opisywać przez dwa rodzaje warunków: wstępne (ang. preconditions) i końcowe (ang. postconditions). Opisują one wymagany i oczekiwany stan fragmentu systemu wymagany odpowiednio przed i po wykonaniu operacji. Pozwala to na precyzyjniejsze opisane zadania realizowanego przez metodę, jej wymagań i efektów jej wykonania. Projektant ma możliwość wyrażenia poprzez nie, jakie warunki muszą być spełnione w celu poprawnego wykonania zadania przez operację. W tym przykładzie warunkiem wstępnym poprawnego wykonania operacji wyszukaj() jest przekazanie niepustego parametru reprezentującego tytuł wydawnictwa, a warunkiem końcowym – zwrócenie wartości różnej od null będącej tablicą typu Wydawnictwo. Operacja wyszukaj() nie gwarantuje określonego rozmiaru zwracanej tablicy. post: wynik != null wynik instanceof Wydawnictwo[] UML cz. I
Relacje pomiędzy klasami Bartosz Walter Relacje pomiędzy klasami zależność – zmiana jednej klasy wpływa na drugą asocjacja – obiekty klas są czasowo ze sobą powiązane agregacja – obiekt jednej klasy jest częścią obiektu drugiej klasy kompozycja – obiekt jednej klasy należy do obiektu drugiej klasy uogólnienie – jedna klasa (podklasa) jest szczególnym przypadkiem drugiej klasy (nadklasy) Na kolejnych slajdach przedstawionych zostanie pięć podstawowych rodzajów relacji, jakie mogą łączyć klasy i obiekty: zależność, asocjację, agregację, kompozycję i dziedziczenie. Są one uporządkowane wg siły relacji, od najsłabszej do najsilniejszej. UML cz. I
Bartosz Walter Zależność Zależności są najprostszym i najsłabszym rodzajem relacji łączących klasy. Oznaczają, że zmiana jednej z nich w pewien sposób wpływa na drugą, np. «call» - operacje w klasie A wywołują operacje w klasie B «create» - klasa A tworzy instancje klasy B «instantiate» - obiekt A jest instancją klasy B «use» - do zaimplementowania klasy A wymagana jest klasa B Zależność między klasami jest najsłabszym typem relacji, jaka może między nimi zaistnieć. Ma ona miejsce wówczas, gdy zmiana definicji jednej klasy może spowodować zmianę drugiej. Zwykle zależność jest jednokierunkowa (zależności dwukierunkowe są oznaczane wprost jako dwie relacje jednokierunkowe). Zależności często opisuje się frazą "...korzysta z...", "...oddziałuje na...", "...ma wpływ na...", "...tworzy...". Z uwagi na różny rodzaj zależności, przy ich opisie stosuje się tzw. słowa kluczowe (ang. keywords), które doprecyzowują znaczenie zależności. Duża liczba zależności istniejących w każdym, nawet niewielkim systemie powoduje, że nie warto przedstawiać ich wszystkich, a skoncentrować się jedynie na zależnościach nieoczywistych, istotnych z punktu widzenia zrozumienia diagramu. Zależności są oznaczane linią przerywaną, a o rodzaju zależności decyduje słowo kluczowe umieszczone nad linią. «call» UML cz. I
Bartosz Walter Asocjacja Asocjacja reprezentuje czasowe powiązanie pomiędzy obiektami dwóch klas. Obiekty związane asocjacją są od siebie niezależne. Asocjacja jest też używana jako alternatywny (obok atrybutu) i równorzędny sposób zapisu cech klasy. Asocjacje są silniejszymi relacjami niż zależności. Wskazują, że obiekt jednej klasy jest związany z obiektem innej klasy przez pewien okres czasu. Czas życia obu obiektów nie jest od siebie zależny: usunięcie jednego nie powoduje usunięcia drugiego. Relacje asocjacji są zwykle opisywane frazami "...posiada...", "...jest właścicielem...", co może mylnie sugerować istnienie relacji typu całość-część, związanej z inną relacją – agregacją. W przypadku asocjacji w rzeczywistości żaden z uczestniczących z niej obiektów nie jest właścicielem drugiego: nie tworzy go, nie zarządza nim, a moment usunięcia drugiego obiektu nie zależy od momentu usunięcia pierwszego. Od strony implementacyjnej, obiekt powiązany asocjacją z drugim posiada referencję do niego, może się do niego odwołać, zna jego typ etc. Asocjacje mogą posiadać nazwy, zapisywane zwykle w postaci czasownika, który pozwala zapisać jej znaczenie w języku naturalnym, np. „A posiada B”. W przypadku asocjacji dwukierunkowych jedną z nazw często pomija się, jeżeli jest ona jedynie stroną bierną drugiej nazwy, np. „przechowuje” – „jest przechowywany”. Asocjacja w warstwie semantycznej jest równoważna atrybutowi klasy: UML nie rozróżnia obiektu, który jest polem klasy od obiektu, który jest z nią związany asocjacją. Warto jednak przyjąć konwencję, w której obiekty reprezentujące wartości (np. daty) oraz typy proste (liczby, napisy, znaki) są modelowane jako atrybuty, natomiast obiekty dostępne poprzez referencje – przedstawiane jako asocjacje. UML cz. I
Nawigowalność asocjacji Bartosz Walter Nawigowalność asocjacji Nawigowalność określa wiedzę o sobie nawzajem obiektów uczestniczących w relacji. Czytelnik wie o swoich rezerwacjach. Rezerwacja nie odwołuje się do czytelnika Informację o kierunku relacji (czyli który obiekt posiada wiedzę o drugim i może odwołać się do niego) opisuje jej nawigowalność. Nawigowalność pomiędzy klasą A i klasą B oznacza, że od obiektu klasy A można przejść do obiektu klasy B, ale nie odwrotnie. Nawigowalność dwukierunkowa oznacza, że nawigując od obiektu klasy A do obiektu klasy B, a następnie z powrotem, w zbiorze wyników (niezależnie od krotności relacji) można znaleźć początkowy obiekt klasy A. Nawigowalność oznaczana jest na diagramach zwrotem (grotem strzałki) umieszczonym na linii pomiędzy klasami, reprezentującej relację. W przypadku nawigowalności dwukierunkowej obie strzałki są pomijane. Oba obiekty pozwalają na nawigację do siebie nawzajem UML cz. I
Bartosz Walter Klasa asocjacyjna Klasy asocjacyjne są związane z relacją asocjacji i opisują jej właściwości. Mają dostęp do innych obiektów uczestniczących w relacji Klasa asocjacyjna umożliwia opisanie za pomocą atrybutów i operacji nie obiektu, ale właśnie samej asocjacji pomiędzy klasami. Informacje przechowywane w klasie asocjacyjnej nie są związane z żadną z klas uczestniczących w asocjacji, dlatego właśnie wygodnie jest stworzyć dodatkową klasę i powiązać ją z relacją. Klasy asocjacyjne są reprezentowane graficznie jako klasy połączone linią przerywaną z relacją asocjacji, której dotyczą. opisuje datę złożenia rezerwacji i kanał (telefon, www) UML cz. I
Asocjacja kwalifikowana Bartosz Walter Asocjacja kwalifikowana Asocjacja kwalifikowana pozwala wskazać, który atrybut jednej z klas służy do zapewnienia unikatowości związku (jest jego kwalifikatorem). Asocjacja kwalifikowana jest rozszerzeniem zwykłej asocjacji o możliwość określenia, który z atrybutów jednej z klas decyduje o istnieniu związku między nimi. Na przykład, składając Rezerwację, Czytelnik podaje listę Wydawnictw, które chciałby pożyczyć. Innymi słowy, między Rezerwacją a Czytelnikiem występuje relacja typu wiele-jeden. Jednak w danym momencie Czytelnik może zarezerwować dane Wydawnictwo tylko jeden raz – i dlatego atrybut id_wydawnictwa jest kwalifikatorem tej relacji. W efekcie pomiędzy instancją Czytelnika a instancją Rezerwacji występuje relacja jeden-jeden, ponieważ konkretny Czytelnik rezerwuje konkretne Wydawnictwo w danym momencie tylko raz. UML cz. I
Bartosz Walter Agregacja Agregacja reprezentuje relację typu całość-część, w której część może należeć do kilku całości, a całość nie zarządza czasem istnienia części. Agregacja jest silniejszą formą relacji niż asocjacja. W przypadku tej relacji równowaga między powiązanymi klasami jest zaburzona: wyróżnia się właściciela relacji i zależny od niego obiekt podrzędny, które są ze sobą powiązane m.in. liniami życia. Obiekt właściciela (w przypadku agregacji) niekoniecznie jest wyłącznym właścicielem obiektu podrzędnego, zwykle też nie tworzy i nie usuwa go. Relacja agregacji jest oznaczana białym rombem umieszczonym na linii reprezentującej relację po stronie obiektu właściciela. Katalog zawiera karty wydawnictw, ale nie tworzy ich. Nie jest ich wyłącznym właścicielem UML cz. I
Bartosz Walter Kompozycja Kompozycja jest relacją typu całość-część, w której całość jest wyłącznym właścicielem części, tworzy je i zarządza nimi. Kompozycja jest najsilniejszym rodzajem relacji, jaka może łączyć klasy, i jednocześnie można ją określić jako szczególny przypadek agregacji. Kompozycja reprezentuje relację typu 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 całości obiekty części są również usuwane. Typowa fraza związana z taką relacją to "...jest częścią...". Kompozycja jest przedstawiana na diagramie podobnie jak agregacja, przy czym romb jest wypełniony. Książka składa się z tomów. Tom nie może istnieć bez pojęcia książki, ani książka bez tomów. UML cz. I
Bartosz Walter Uogólnienie Uogólnienie tworzy hierarchię klas, od ogólnych do bardziej szczegółowych. Pozwala wyłączyć części wspólne klas. Klasa ogólna Ostatnia z relacji wiążących klasy – uogólnienie – posiada nieco inną naturę i można ją interpretować na różne sposoby. Na przykład, w modelu pojęciowym Katalog jest uogólnieniem Katalogu rzeczowego, jeżeli każda instancja Katalogu rzeczowego jest także instancją Katalogu. Inną interpretacją posiadanie przez grupę katalogów specjalizowanych (rzeczowego, autorskiego i alfabetycznego) tych samych cech, które są reprezentowane przez wspólną nadklasę – Katalog. Uogólnienie w przypadku klas często jest traktowane jako synonim dziedziczenia, podczas gdy dziedziczenie jest jedną z możliwych technik stosowania uogólnienia. Inną jest np. wykorzystanie interfejsów, które pozwalają utworzyć relację uogólnienia/uszczegółowienia pomiędzy typami (dziedziczenie interfejsu) lub klasą i interfejsem (implementacja interfejsu). Klasy szczegółowe UML cz. I
{overlapping, incomplete} Bartosz Walter Klasyfikacja Klasyfikacja określa związek między obiektem a jego typem (klasą). Obiekt może należeć jednocześnie do wielu typów. {overlapping} – obiekt może należeć do kilku klas {disjoint} – obiekt może należeć tylko do jednej klasy {complete} – nie istnieje więcej podklas {incomplete} – mogą powstać kolejne podklasy {disjoint, complete} Nieco innym pojęciem związanym z relacją uogólnienia jest klasyfikacja obiektu. W odróżnieniu od relacji uogólnienia opisuje ona związek pomiędzy obiektami a klasami. Klasyfikacja obiektu określa, z którymi typami (klasami) obiekt jest powiązany – poprzez dziedziczenie, interfejsy etc. Ponieważ obiekt może jednocześnie uczestniczyć w wielu niezależnych klasyfikacjach (a zatem posiadać wiele typów), dlatego do szczegółowego określenia natury klasyfikacji stosowane są uściślające słowa kluczowe: {overlapping} oznacza, że obiekt może jednocześnie należeć do kilku klas/posiadać wiele typów. Na przykład Wydawnictwo, mimo że posiada dwie podklasy: Książka Czasopismo, może wystąpić w postaci łączącej obie te cechy. Przeciwieństwem jest słowo kluczowe {disjoint}, które narzuca rozłączność typów danych {complete} oznacza, że wymienione dotychczas podklasy w ramach jednej specjalizacji są wyczerpujące i nie istnieje kategoria, która znalazłaby się poza nimi. W przykładzie Wydawnictwo może być Ogólne lub Specjalizowane, i nie przewiduje się istnienia nowej podklasy. {Incomplete} dopuszcza taką możliwość. {overlapping, incomplete} UML cz. I
Interfejsy i klasy abstrakcyjne Bartosz Walter Interfejsy i klasy abstrakcyjne Klasa abstrakcyjna deklaruje wspólną funkcjonalność grupy klas. Nie może posiadać obiektów i musi definiować podklasy. Interfejs deklaruje grupę operacji bez podawania ich implementacji. 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. Użycie tych mechanizmów pozwala na wykorzystanie relacji uogólniania do ukrywania (hermetyzacji) szczegółów implementacji poszczególnych klas. Klasa abstrakcyjna reprezentuje wirtualny byt grupujący wspólną funkcjonalność kilku klas. Posiada ona sygnatury operacji (czyli deklaracje, że klasy tego typu będą akceptować takie komunikaty), ale nie definiuje ich implementacji. Podobną rolę pełni interfejs. Różnica polega na tym, że klasa abstrakcyjna może posiadać implementacje niektórych operacji, natomiast interfejs jest czysto abstrakcyjny (choć, oczywiście interfejs i klasa w pełni abstrakcyjna są pojęciowo niemal identyczne). Ponieważ klasy abstrakcyjne nie mogą bezpośrednio tworzyć swoich instancji (podobnie jak interfejsy, które z definicji nie reprezentują klas, a jedynie ich typy) dlatego konieczne jest tworzenie ich podklas, które zaimplementują odziedziczone abstrakcyjne metody. W przypadku interfejsu sytuacja jest identyczna. Przyjętym sposobem oznaczania klas i metod abstrakcyjnych jest zapisywanie ich pochyłą czcionką lub opatrywanie słowem kluczowym {abstract}. W przykładzie Katalog jest klasą abstrakcyjną posiadającą abstrakcyjne metody Sortowanie() i Znajdź(). Metody te posiadają implementacje w podklasie Katalog alfabetyczny. Katalog implementuje interfejs Sortowalny (z metodą Porównaj()), który z kolei jest wymagany przez klasę pomocniczą Narzędzia. implementowany interfejs wymagany interfejs UML cz. I
Bartosz Walter Szablony klas Szablon klasy określa, z jakimi innymi klasami (nie obiektami!) może współpracować podana klasa. Klasy te są przekazywane jako jej parametry. Klasa będąca uszczegółowieniem takiej klasy jest klasą związaną. parametr klasy Lista «bind» Szablony klas to pojęcie wywodzące się z języka C++. Oznaczają one klasy, których definicja wymaga podania parametrów będących innymi klasami. W ten sposób szablon klasy jest swego rodzaju niepełną klasą, która dopiero po ukonkretnieniu (czyli właśnie podaniu parametrów) może zostać użyta w programie. Na przykład, klasa Lista może przechowywać obiekty pewnego dowolnego, ale określonego typu. Typ ten może stać się parametrem tej klasy: w ten sposób utworzony zostanie szablon listy, która może przechowywać elementy potencjalnie dowolnego typu. Klasa stanowiąca ukonkretnienie szablonu (ListaWydawnictw) została sparametryzowana (związana, ang. bound – do opisu tego typu zależności służy słowo kluczowe bind) typem Wydawnictwo, dzięki czemu może być już wykorzystana bezpośrednio w programie. Podobną koncepcję wprowadzono także do innych języków programowania, np. Java czy C#, pod nazwą typów generycznych lub właśnie szablonów. klasa związana szablon klasy Lista UML cz. I
Bartosz Walter Diagram obiektów Diagram obiektów przedstawia możliwą konfigurację obiektów występujących w systemie. Relacje pomiędzy obiektami są bardziej dynamiczne niż w przypadku klas. Diagram obiektów (ang. object diagram) jest blisko związany z diagramem klas i prezentuje możliwą konfigurację obiektów w określonym momencie. Jest zatem pewnego rodzaju migawką diagramu klas, w której zamiast klas przedstawiono ich obiekty. Diagram ten posługuje się identycznymi symbolami co diagram klas, jednak, dla odróżnienia obiektów od klas, nazwy instancji są podkreślone. Ponadto, nazwa składa się z nazwy obiektu i nazwy klasy, oddzielonych dwukropkiem. Obie części nazwy można pominąć, więc aby uniknąć nieporozumień, jedna część nazwy oznacza nazwę obiektu, a sama nazwa klasy musi być zawsze poprzedzona dwukropkiem. Diagramy obiektów przydają się w przypadku szczególnie skomplikowanych zależności, których nie można przedstawić na diagramie klas. Wówczas przykładowe konfiguracje obiektów pomagają w zrozumieniu modelu. UML cz. I
Diagram struktur złożonych Bartosz Walter Diagram struktur złożonych Diagram struktur złożonych przedstawia wewnętrzną strukturę obiektu oraz punkty interakcji z innymi obiektami w systemie. obiekt złożony port Wyszukiwanie Katalog część «defines» Wyszukiwarka interfejs Diagram struktur złożonych (ang. composite structure diagram) jest kolejnym, wprowadzonym w wersji 2.0 UML diagramem służącym do przedstawiania logicznej struktury obiektu. Prezentuje on hierarchicznie wewnętrzną strukturę złożonego obiektu z uwzględnieniem punktów interakcji z innymi częściami systemu, a więc jego poziom szczegółowości jest znacznie wyższy niż w przypadku np. diagramu klas i obiektów, skupiających się jedynie na całych klasach. Obiekt złożony składa się z części, które reprezentują poszczególne składowe obiektu realizujące poszczególne funkcje obiektu. Komunikacja pomiędzy obiektem, a jego środowiskiem przebiega poprzez port (oznaczany jako mały prostokąt umieszczony na krawędzi obiektu). Porty są połączone z częściami obiektu, które są odpowiedzialne za realizacje tych funkcji. Diagramy struktur złożonych mogą także zawierać interfejsy wewnętrzne (równoważne klasom w pełni abstrakcyjnym) i interfejsy udostępnione (widoczne na zewnątrz obiektu). «defines» Baza danych Zarządzanie danymi UML cz. I
Bartosz Walter Podsumowanie UML powstał w wyniku połączenia różnych notacji i metodyk modelowania UML opisuje system w postaci 4 perspektyw wewnętrznych i 1 zewnętrznej Diagram przypadków użycia opisuje funkcje systemu i jego użytkowników Diagram klas określa statyczną strukturę logiczną systemu Diagram obiektów pokazuje możliwą konfigurację obiektów w systemie Podczas wykładu przedstawiono genezę języka UML, jego strukturę, oraz cztery typy diagramów: przypadków użycia, należący do perspektywy przypadków użycia, oraz diagramy klas, obiektów i struktury złożonej, służące do modelowania struktury logicznej programu. UML cz. I