Komponenty wydzielaj według odpowiedzialności i kontraktu#
Podział systemu na komponenty powinien grupować powiązane zachowanie i dane w elementy o czytelnych granicach oraz jawnych kontraktach. Komponent UML jest wymienialną, kapsułkowaną częścią systemu, która udostępnia usługi przez interfejsy i może wymagać usług innych elementów. Dobre granice ułatwiają rozumienie, rozwój i zmianę systemu; sam diagram nie gwarantuje jednak, że architektura będzie łatwa w utrzymaniu.
Nie dziel systemu wyłącznie według liczby klas, folderów, zespołów lub technologii. Jedna funkcja biznesowa może obejmować wiele klas, a jedna aplikacja może zawierać kilka komponentów logicznych. Najpierw określ perspektywę: architekturę logiczną, wdrażalne moduły, subsystemy, usługi czy komponenty wykonawcze. Słowo „komponent” bywa używane szeroko, więc opisz zakres diagramu.
Zacznij od wymagań, zmian i odpowiedzialności#
Wypisz funkcje systemu, główne pojęcia, źródła danych, reguły i integracje. Szukaj grup, które zmieniają się z podobnych powodów, realizują spójny cel i mają wyraźny kontrakt z otoczeniem. Sprawdź, które obszary mogą być rozwijane lub zastępowane niezależnie.
Przydatne pytania:
- Które zachowania należą do tej samej funkcji lub kontekstu domenowego?
- Jakie dane i reguły powinny być chronione za granicą komponentu?
- Które decyzje projektowe mogą się zmieniać niezależnie?
- Jakie usługi komponent udostępnia innym?
- Jakich usług potrzebuje od otoczenia?
- Czy każda zależność ma uzasadniony kierunek i stabilny kontrakt?
- Czy model pomaga lokalizować odpowiedzialność za zmianę lub awarię?
Są to kryteria do oceny, nie automatyczna formuła. Wymagania organizacyjne, niezawodność, bezpieczeństwo i możliwości wdrożeniowe mogą uzasadnić inne granice niż sama domena biznesowa.
Interfejsy dostarczane i wymagane#
Interfejs dostarczany (provided interface) opisuje usługi, które komponent oferuje. Interfejs wymagany (required interface) wskazuje usługi, z których komponent korzysta. Połączenie wymagania z dostawcą wyjaśnia kontrakt między elementami i pozwala zauważyć, że komponent nie jest samowystarczalny.
Nie utożsamiaj interfejsu UML wyłącznie z interfejsem języka programowania. Może oznaczać kontrakt logiczny, API, port protokołu, zbiór operacji lub inny punkt współpracy. Konkretna technologia, format komunikatu i wersjonowanie należą do szczegółów, jeśli diagram ma pozostać na wyższym poziomie.
Port (port) jest punktem interakcji klasyfikatora z otoczeniem i może grupować dostarczane lub wymagane interfejsy. Użyj portu, gdy trzeba pokazać miejsce podłączenia, rolę lub granicę komunikacji komponentu. Nie dodawaj portów do prostego diagramu zależności, jeśli nie wnoszą informacji.
Zależności i kierunek zmian#
Zależność pokazuje, że jeden komponent korzysta z usług drugiego. Strzałkę skieruj od klienta zależności do dostawcy lub wymaganego kontraktu zgodnie z używaną notacją. Interfejs jako jawny element może pomóc oddzielić kontrakt od implementacji, zwłaszcza gdy wielu dostawców może go realizować.
Oceniaj nie tylko liczbę połączeń, ale także ich kierunek, stabilność i wpływ zmian. Cykliczne zależności mogą utrudniać niezależne rozwijanie elementów. Kontrakt powinien być możliwie mały i ukierunkowany na potrzebę klienta; ogólny „interfejs do wszystkiego” ukrywa rzeczywiste sprzężenie.
Przykład: sklep internetowy#
Interfejs sklepu korzysta z katalogu i obsługi zamówień. Komponent zamówień wymaga kontraktu płatniczego, który dostarcza bramka. Dzięki temu można rozmawiać o zamianie dostawcy bez uzależniania modelu od konkretnej biblioteki lub klasy implementacyjnej. Diagram nie pokazuje protokołu, autoryzacji, retry ani sposobu wdrożenia komponentów.
Oceń jakość granic#
Spójny komponent skupia odpowiedzialności, które należą do siebie; luźne sprzężenie ogranicza wiedzę o szczegółach innych elementów. W praktyce kompromisy są nieuniknione. Bardzo drobny podział zwiększa liczbę kontraktów, wdrożeń, obsługi błędów i przekazań. Zbyt duży komponent kumuluje niezależne funkcje i utrudnia zmianę.
Przetestuj granice na przykładowych zmianach: nowy dostawca płatności, inna polityka rabatowa, zmiana źródła katalogu, wymaganie odseparowania danych. Sprawdź, które elementy trzeba modyfikować, jak zmiany przepływają przez interfejsy i czy odpowiedzialność pozostaje czytelna.
Awaria jest kolejnym sprawdzianem: który komponent może zawieść, kto wykrywa brak odpowiedzi i jak zachowuje się reszta? Sam komponentowy widok logiczny nie określa redundancji ani izolacji awarii; do tych pytań potrzebne są dodatkowe widoki i wymagania jakościowe.
Powiąż komponenty z innymi diagramami#
Diagram klas może pokazać wewnętrzne typy i relacje komponentu, diagram przypadków użycia — funkcje widoczne dla aktorów, a diagram wdrożenia — węzły wykonawcze i artefakty. Diagram struktury złożonej może zajrzeć do wnętrza komponentu i opisać jego części oraz połączenia.
Nie utożsamiaj komponentu z węzłem wdrożeniowym. Komponent może być realizowany przez artefakt, a artefakt wdrażany na węźle; te pojęcia opisują inne aspekty architektury.
Procedura podziału#
- Określ, czy modelujesz architekturę logiczną, usługi, moduły czy jednostki wdrożeniowe.
- Zbierz funkcje, reguły, dane, integracje i wymagania jakościowe.
- Grupuj odpowiedzialności o spójnym celu i podobnych powodach zmiany.
- Dla każdej granicy nazwij dostarczane i wymagane kontrakty.
- Zaznacz zależności i sprawdź ich kierunek oraz stabilność.
- Przetestuj podział na scenariuszach zmian, awarii i rozwoju zespołów.
- Usuń granice, które tylko rozpraszają proste zachowanie bez korzyści.
- Uzupełnij innym diagramem aspekt, którego ten widok nie pokazuje.
Typowe błędy#
- Komponent jako arbitralna grupa klas. Powinien mieć sensowną odpowiedzialność i granicę.
- Podział według technologii bez kontekstu. Stack może się zmienić, a podział funkcji nadal powinien wyjaśniać system.
- Brak kontraktów. Połączenie bez znaczenia nie informuje, co komponent oferuje.
- Interfejs jako etykieta dekoracyjna. Pokaż rzeczywisty dostarczany lub wymagany kontrakt.
- Każdy moduł jako osobna usługa. Granica logiczna nie przesądza o mikroserwisie ani wdrożeniu.
- Komponent mylony z serwerem. Węzeł wdrożenia i komponent to inne elementy modelu.
- Zbyt wiele portów i operacji. Szczegóły kontraktu powinny odpowiadać celowi diagramu.
- Cykliczne zależności bez uzasadnienia. Mogą utrudnić niezależne zmiany i testowanie.
- Ignorowanie wymagań jakościowych. Bezpieczeństwo, dostępność i opóźnienia wpływają na granice.
- Brak scenariusza zmiany. Podział oceniaj na realnych potrzebach, nie tylko estetyce diagramu.
Lista kontrolna#
- Czy wiadomo, co oznacza „komponent” i na jakim poziomie jest diagram?
- Czy każda granica grupuje spójną odpowiedzialność?
- Czy kontrakty dostarczane i wymagane są jawne?
- Czy zależności mają uzasadniony kierunek?
- Czy podział wspiera przewidywane zmiany, testowanie i odpowiedzialność?
- Czy odróżniono komponenty logiczne od artefaktów i węzłów wdrożenia?
- Czy diagram pokazuje tylko szczegóły potrzebne odbiorcy?
Dobry podział komponentów wynika z odpowiedzialności i kontraktów, a następnie jest sprawdzany na zmianach, awariach i sposobie pracy zespołów. Diagram UML pomaga wyjaśnić granice, ale nie zastępuje decyzji architektonicznych ani uzasadnienia kompromisów.