Czym jest diagram pakietów#
Diagram pakietów (package diagram) pokazuje, jak elementy modelu są grupowane w pakiety, jak pakiety są zagnieżdżone oraz jakie zależności występują między ich zawartością. Jest przydatny do przedstawiania przestrzeni nazw, dużych modeli i wybranych granic organizacyjnych. Zwykle pokazuje strukturę na poziomie wyższym niż diagram klas: może ukryć wnętrze pakietów i skupić się na zależnościach między nimi.
Pakiet w UML jest przestrzenią nazw i może grupować elementy modelu. Wewnątrz pakietu nazwy elementów muszą być jednoznaczne zgodnie z regułami przestrzeni nazw. Elementy mogą być wskazywane nazwą kwalifikowaną, która uwzględnia pakiety nadrzędne, np. Sklep::Zamówienia::Zamówienie.
Pakiet nie jest z definicji folderem na dysku, modułem języka programowania, warstwą architektury ani osobną usługą. Zespół może odwzorować go na takie konstrukcje, ale to decyzja implementacyjna. Diagram powinien pokazywać, czy grupowanie jest logiczne, czy odpowiada fizycznej strukturze kodu.
Kiedy używać diagramu pakietów#
Użyj go, gdy trzeba uporządkować rozległy model, pokazać jego przestrzenie nazw, omówić zależności między obszarami lub przeanalizować granice modularności. Diagram może pomóc zauważyć cykle zależności, zbyt szeroką widoczność, pakiety o niejasnej odpowiedzialności i miejsca, w których zmiany mogą rozchodzić się na wiele obszarów.
Może obejmować pakiety zawierające klasy, przypadki użycia, komponenty lub inne elementy UML. W prostym widoku można pokazać same pakiety i relacje między nimi, bez prezentowania całej zawartości. W bardziej szczegółowym widoku warto pokazać przykładowe klasyfikatory, jeżeli bez nich nie wiadomo, co dany pakiet grupuje.
Diagram nie pokazuje szczegółów zachowania, konkretnych instancji ani fizycznego wdrożenia. Do interakcji użyj diagramu zachowania, do klas — diagramu klas, a do rozmieszczenia na węzłach — diagramu wdrożenia.
Podstawowe elementy#
Pakiet i jego zawartość#
Pakiet jest przedstawiany jako prostokąt z małą zakładką lub jako prostokąt z nazwą; można go narysować z dodatkowym przedziałem zawartości. Nazwa powinna opisywać spójny obszar modelu. Jeżeli elementy są pokazane w środku pakietu, ich umiejscowienie oznacza przynależność do jego przestrzeni nazw, a nie tylko wizualne sąsiedztwo.
Pakiet może zawierać inne pakiety. Zagnieżdżenie określa relację przestrzeni nazw: element pakietu wewnętrznego jest identyfikowany w kontekście pakietu nadrzędnego. Nie należy z samej geometrii prostokątów wyciągać wniosku o zależności pomiędzy pakietem nadrzędnym i podrzędnym.
Przy dużych modelach można pokazywać pakiet z pominiętą zawartością. Jest to świadome pominięcie w diagramie, nie dowód, że pakiet jest pusty. Jeśli ważne jest, jakie elementy są publiczne lub dostępne z zewnątrz, pokaż je albo opisz konwencję widoczności.
Zależność#
Zależność między pakietami wskazuje, że elementy jednego pakietu korzystają z elementów drugiego. Często rysuje się ją jako linię przerywaną ze strzałką od pakietu zależnego (klienta) do dostawcy. Zwykła zależność jest ogólniejsza; jej kierunek pomaga ocenić wpływ zmian, lecz nie określa mechanizmu importu ani konkretnej konstrukcji języka.
Zależności warto nazwać lub opatrzyć stereotypem, gdy wiadomo, jakiego rodzaju relację pokazują. UML definiuje wyspecjalizowane relacje pakietowe, w tym import i scalanie. Nie są one wymiennymi wariantami zwykłego „używa”.
Import pakietu#
Import pakietu («import») wskazuje, że przestrzeń nazw pakietu źródłowego uzyskuje dostęp do elementów przestrzeni nazw pakietu docelowego pod ich niekwalifikowanymi nazwami. Elementy pakietu docelowego nie są przez to przenoszone ani usuwane z jego własnej przestrzeni nazw. Widoczność importowanych elementów i sposób udostępnienia nazw zależą od rodzaju importu oraz widoczności elementów.
Na diagramie relacja jest skierowana od pakietu importującego do importowanego. Oznacza to, że strzałka wskazuje dostawcę elementów, których używa źródło. Import pakietu różni się od kopiowania klas do innego pakietu.
Dostęp do pakietu#
Dostęp pakietu («access») jest relacją, w której pakiet źródłowy uzyskuje dostęp do elementów innego pakietu, ale importowane nazwy nie są w taki sam sposób włączane do jego przestrzeni nazw, jak przy imporcie. Nazwy mogą wymagać kwalifikacji. Oznaczenie jest przydatne, gdy model ma rozróżniać rodzaj dostępu.
Nie każdy zespół potrzebuje używać «access» w codziennej dokumentacji. Jeśli diagram pokazuje ogólną zależność architektoniczną, zwykła zależność może być wystarczająca — pod warunkiem że nie udaje bardziej szczegółowej relacji niż rzeczywiście zamodelowano.
Scalanie pakietów#
Scalanie pakietów («merge») jest relacją służącą do łączenia definicji modelu w przestrzeni nazw. Elementy o zgodnych nazwach w pakietach uczestniczących w scaleniu są interpretowane według reguł scalania, a definicja źródłowa może zostać rozszerzona o definicję z pakietu docelowego. Pakiet docelowy nie jest po prostu kopiowany ani modyfikowany przez każdą zmianę w źródle.
Jest to zaawansowany mechanizm modelowania, nie ogólne słowo na „łączy się z”. Używaj go tylko wtedy, gdy rzeczywiście modelujesz scalanie definicji i rozumiesz jego skutki. Dla zwykłego użycia elementów wybierz zależność lub import.
Przykład: pakiety sklepu#
Diagram przedstawia pakiet aplikacji sklepu oraz pakiet domeny, w którym zgrupowano zamówienia i katalog. Aplikacja importuje model domenowy, a pakiet integracji udostępnia jej elementy poprzez zależność dostępu. Zagnieżdżenie pakietów domenowych obrazuje podział przestrzeni nazw.
Strzałka od Aplikacja do Domena wskazuje pakiet importowany. Elementy Zamówienie i Produkt należą do zagnieżdżonych przestrzeni nazw domeny. Zależność od Integracje ma w tym przykładzie etykietę «access», co sygnalizuje dostęp bez przyjmowania skrótu importu.
Przykład jest celowo uproszczony. Nie stwierdza, że aplikacja powinna zależeć od konkretnej klasy adaptera płatności; produkcyjny model mógłby wydzielić kontrakt i implementację albo zastosować odwrócenie zależności. Diagram nie jest też deklaracją struktury folderów projektu. Etykiety pokazują zamierzony rodzaj zależności w modelu, a nie automatyczny generator kodu.
Jak tworzyć diagram pakietów#
- Ustal perspektywę. Określ, czy grupujesz elementy domeny, projekt, moduły kodu czy przestrzenie nazw większego modelu.
- Znajdź spójne grupy. Umieszczaj razem elementy, których nazwy, odpowiedzialności lub cykl zmian tworzą sensowną całość.
- Nadaj pakietom jednoznaczne nazwy. Unikaj etykiet ogólnych, takich jak
Różne,CommonlubUtils, jeśli nie wiadomo, co zawierają. - Pokaż istotne zagnieżdżenia. Używaj ich do wyrażenia struktury przestrzeni nazw, nie tylko do wymuszenia układu grafiki.
- Wybierz właściwy rodzaj relacji. Zwykła zależność,
«import»,«access»i«merge»mają różne znaczenia. - Ogranicz szczegóły zawartości. Dodaj elementy wewnętrzne tylko wtedy, gdy tłumaczą podział lub konkretną zależność.
- Sprawdź kierunek zależności i cykle. Ustal, kto jest klientem, a kto dostawcą; zbadaj, czy zależności nie tworzą niezamierzonych pętli.
- Porównaj diagram z modelem lub kodem. Jeśli diagram ma odzwierciedlać istniejący projekt, upewnij się, że grupowanie i widoczność są aktualne.
Diagram pakietów jest narzędziem do podejmowania i komunikowania decyzji o organizacji modelu. Nie każda dobra organizacja kodu musi być odtworzona jeden do jednego w modelu UML, a sama hierarchia folderów nie przesądza o jakości granic.
Jak czytać zależności#
Najpierw ustal kierunek: pakiet, z którego wychodzi strzałka, jest zależny albo importuje; grot wskazuje dostawcę. Następnie przeczytaj etykietę relacji. Wreszcie sprawdź, czy pokazane elementy wewnętrzne należą do przestrzeni nazw danego pakietu, czy zostały jedynie wyróżnione jako przykłady.
Jeżeli A zależy od B, zmiany w B mogą wymagać aktualizacji A. Wiele zależności skierowanych do wspólnego pakietu może wskazywać na jego rolę jako dostawcy wspólnych abstrakcji, ale także na ryzyko nadmiernego sprzężenia. Cykl A → B → A utrudnia niezależne zmiany i może oznaczać, że granice wymagają ponownego przemyślenia. Sam diagram nie przesądza, że cykl jest błędem — ujawnia zależność, którą należy ocenić w kontekście.
Nie odczytuj z diagramu więcej, niż zawiera. Brak strzałki może oznaczać brak zależności, ale może też być pominięciem dla czytelności. Warto określić, czy diagram jest kompletny dla wskazanego zakresu, czy pokazuje wybrane relacje.
Diagram pakietów a foldery, komponenty i klasy#
| Pojęcie lub diagram | Co opisuje |
|---|---|
| Pakiet UML | Grupę elementów i przestrzeń nazw modelu. |
| Folder w systemie plików | Fizyczne miejsce przechowywania plików. |
| Diagram klas | Klasyfikatory, ich cechy i relacje strukturalne. |
| Diagram komponentów | Modularne części systemu i ich kontrakty. |
| Diagram pakietów | Grupowanie elementów oraz zależności między pakietami. |
Zespół może zdecydować, że pakiet UML odpowiada folderowi, modułowi lub projektowi kodu. Warto wtedy opisać regułę mapowania, ponieważ UML sam nie ustanawia takiej równoważności dla każdego języka i narzędzia.
Typowe błędy#
- Traktowanie pakietu jak zwykłego folderu. Pakiet ma semantykę przestrzeni nazw modelu; powiązanie z folderem jest konwencją.
- Używanie pakietów wyłącznie do układania prostokątów. Zagnieżdżenie powinno pokazywać rzeczywistą strukturę nazw lub grupowanie.
- Mylenie zagnieżdżenia z zależnością. Umieszczenie jednego pakietu wewnątrz drugiego wyraża zawieranie w przestrzeni nazw, a nie samo użycie.
- Odwrócenie strzałki. Strzałka zależności prowadzi od klienta do dostawcy; sprawdź kierunek, czytając relację na głos.
- Zamiana
«import»,«access»i«merge». Każda z tych relacji opisuje inny mechanizm przestrzeni nazw. - Pokazywanie wszystkich elementów naraz. Diagram ma wyjaśniać organizację i zależności, a nie zastępować wszystkie diagramy klas.
- Pakiet „Wspólne” bez odpowiedzialności. Ogólny pakiet łatwo staje się niekontrolowanym miejscem na przypadkowe elementy.
- Ignorowanie cykli i zależności wzajemnych. Zaznacz je i sprawdź konsekwencje dla zmian oraz kompilacji.
- Nieprecyzyjne wnioski z braku relacji. Określ, czy pokazano wszystkie zależności z danego zakresu.
Co diagram pakietów pokazuje, a czego nie#
Diagram pakietów pokazuje organizację przestrzeni nazw i wybrane zależności między grupami elementów. Pomaga rozmawiać o granicach dużego modelu i przewidywać, które obszary będą na siebie oddziaływać.
Nie określa automatycznie struktury folderów, granic procesów, sposobu wdrożenia ani pełnej architektury komponentowej. Nie pokazuje też algorytmów ani wszystkich szczegółów klas. Interpretuj go zgodnie z opisaną perspektywą i uzupełniaj innymi diagramami wtedy, gdy pytania dotyczą zachowania, implementacji lub środowiska uruchomieniowego.