Komponent jako modularna część systemu#

Komponent (component) reprezentuje modularną, wymienialną część systemu, której zachowanie jest opisane przez interfejsy dostarczane i wymagane. Może odpowiadać usłudze, bibliotece, podsystemowi lub innemu elementowi architektury. Diagram komponentów skupia się na granicach i kontraktach, a nie na szczegółowej strukturze klas implementacyjnych.

Komponent Sklep wymaga interfejsu IPayment, który dostarcza komponent Platnosci; połączenie pokazuje kontrakt między częściami systemu.
Komponenty współpracują przez jawnie modelowane interfejsy.

Komponent Platnosci realizuje kontrakt IPayment, a Sklep od niego zależy. Diagram mówi, jaki kontrakt łączy moduły; nie określa protokołu sieciowego, adresu usługi, języka programowania ani sposobu wdrożenia. Te informacje wymagają osobnego modelu lub dokumentacji.

Interfejs dostarczany i wymagany#

Interfejs dostarczany (provided interface) to usługi, które komponent oferuje otoczeniu. Interfejs wymagany (required interface) to usługi, których komponent potrzebuje od innych części systemu. Jeden komponent może jednocześnie dostarczać wiele interfejsów i wymagać innych.

W notacji graficznej interfejs dostarczany bywa oznaczany kółkiem na krótkiej linii — „lizakiem”. Wymagany może mieć symbol półokręgu przypominający gniazdo. Połączenie gniazda z lizakiem oznacza, że kontrakt wymagany przez jeden komponent jest dostarczany przez drugi. Prostokątny symbol interfejsu z relacją realizacji i zależności może być czytelniejszy, gdy trzeba pokazać nazwę operacji albo wyjaśnić relację statyczną.

Nie utożsamiaj deklaracji interfejsu z jego dostępnością w czasie wykonania. Komponent może deklarować usługę, ale być niedostępny z powodu awarii, konfiguracji lub braku wdrożenia. Model struktury opisuje zamierzoną architekturę, chyba że wyraźnie modeluje stan uruchomieniowy.

Port jako punkt interakcji#

Port (port) jest określonym punktem interakcji na granicy klasyfikatora, na przykład komponentu. Określa, jakie usługi są dostępne przez dany punkt i jakie usługi komponent wymaga od otoczenia. Port można typować i powiązać z interfejsami. Pozwala odróżnić różne role komunikacyjne tego samego komponentu: na przykład port administracyjny i port obsługi zamówień.

Port jest przedstawiany jako mały prostokąt na obramowaniu komponentu. Sam port nie musi odpowiadać gniazdu sieciowemu, portowi TCP ani fizycznemu złączu. To element modelu, którego znaczenie wynika z kontraktów i połączeń. Jeśli szczegóły protokołu albo adresowania są istotne, opisz je jako właściwości lub w innym widoku.

Łączniki montażowe i delegacyjne#

Łącznik montażowy (assembly connector) łączy wymagany interfejs jednego komponentu z dostarczanym interfejsem innego. Pokazuje, że potrzebny kontrakt ma w systemie realizatora. To relacja między punktami dostarczania i zapotrzebowania, a nie dowód, że wywołanie zakończy się powodzeniem.

Łącznik delegacyjny (delegation connector) łączy zewnętrzny port komponentu z wewnętrzną częścią, która obsługuje wymagany kontrakt. Pozwala pokazać, w jaki sposób widoczna na zewnątrz usługa jest przekazana elementowi wewnętrznej struktury. Jeśli wnętrze nie jest przedmiotem diagramu, nie dodawaj szczegółów implementacji tylko po to, by użyć tego łącznika.

Komponent a pakiet i klasa#

Pakiet grupuje elementy modelu i przestrzenie nazw; komponent wyraża modularną część architektury wraz z kontraktami otoczenia. Klasa opisuje strukturę i zachowanie instancji. Komponent może być realizowany przez wiele klas, inne komponenty lub zasoby, zależnie od poziomu modelu.

Diagram komponentów nie musi odpowiadać bezpośrednio strukturze repozytorium ani procesów. Granice modułów wybieraj według odpowiedzialności i interfejsów. Używanie nazwy „komponent” dla każdego katalogu lub klasy rozmywa różnicę między abstrakcją architektoniczną a kodem.

Kiedy stosować porty#

Porty są przydatne, gdy komponent ma różne kontrakty na różnych punktach granicy, gdy chcesz pokazać wejścia i wyjścia albo gdy struktura wewnętrzna deleguje obsługę interakcji. Przy prostym widoku wystarczy często zaznaczyć interfejsy przy komponencie bez szczegółowego rozmieszczania portów.

Nazwij port według roli i pokaż, które interfejsy dostarcza lub wymaga. Jeśli używasz tej samej nazwy dla portu i interfejsu, wyjaśnij, czy port jest typowany tym interfejsem, czy tylko używa go jako kontraktu. Różne porty mogą wystawiać ten sam interfejs, jeśli pełnią odrębne role.

Typowe błędy#

  • Komponent utożsamiony z klasą. Komponent jest zwykle większą granicą modułową.
  • Interfejs wymagany i dostarczany odwrócone. Jeden opisuje potrzebę konsumenta, drugi oferowaną usługę.
  • Port uznany za port TCP. UML-owy port jest punktem interakcji modelu.
  • Połączenie odczytane jako gwarancja działania. Architektura deklarowana nie dowodzi dostępności.
  • Diagram komponentów przeciążony klasami. Szczegóły implementacji umieszczaj w odpowiednim widoku.
  • Brak kontraktu na granicy. Nazwij interfejsy, aby czytelnik rozumiał, co przepływa między modułami.
  • Łącznik montażowy pomylony z delegacją. Pierwszy łączy zapotrzebowanie z dostawcą, drugi przekazuje zewnętrzną interakcję do wnętrza.

Podsumowanie#

Komponent jest modularną częścią systemu, interfejs opisuje jego kontrakt, a port wyznacza punkt interakcji z otoczeniem. Interfejsy wymagane i dostarczane łączy się, by pokazać zależności architektoniczne. Porty, łączniki montażowe i delegacyjne dodawaj wtedy, gdy wyjaśniają rzeczywistą granicę lub przepływ odpowiedzialności.