Systemy informatyczne są złożone. Jak sobie z tym radzić?
Każdy z nas był w sytuacji kiedy rozpoczynamy zupełnie nowy #projekt lub (nieco gorsza sytuacja) - jesteśmy zmuszeni do pracy nad systemem spadkowym. Oba scenariusze wymagają od nas pewnej #wizualizacji przyszłej #struktury naszego systemu lub odkrycie tego jak aktualny #system funkcjonuje. Najważniejsze jednak, aby taki #diagram mógł stanowić podstawę do komunikacji między różnymi interesariuszami naszego projektu – programistami, product owner’em, klientami itd. Każdy z nas ma swój własny sposób budowania tego rodzaju diagramów. Czy są one jednak zrozumiałe dla każdego w naszym zespole? Czy sami jesteśmy w stanie zrozumieć własny diagram za tydzień, miesiąc lub rok. Przyjrzymy się kilku przykładom.
Podejście 1 – burza mózgów
Innymi słowy bierzemy tablicę i zaczynamy rysować. Efektem takiej burzy mózgów jest zazwyczaj diagram, który pod koniec dnia digitalizujemy – robiąc zdjęcia telefonem, aby personel sprzątający nasze biuro nie usunął w nocy naszego „projektu”. Poniżej widzimy zdjęcie diagramu z naszego biura – sprzed ok. roku.
Jako element burzy mózgów – z pewnością powyższy diagram zapewne był w swoim czasie zrozumiały. Jednak czy teraz pamiętamy o co właściwie chodziło? Czy ktokolwiek pamięta dokładnie dlaczego „Hurtownia” jest w cudzysłowie. Diagram nie jest czytelny. Nie może służyć zarówno jako element dokumentacji, ani jako element komunikacji między członkami zespoły lub komunikacji z klientem. Każdy developer/architekt wykorzysta swoją notację (której sami później nie rozumiemy). Spróbujmy zatem przypomnieć sobie pewien nieco bardziej ustrukturyzowany system dokumentacji architektury.
Podejście 2 – UML
Figure 1- https://en.wikipedia.org/wiki/Class_diagram
Pewnie każdy z nas napotkał na swojej drodze napotkał język UML. Niektórzy musieli się z nim męczyć na studiach, inni poznali jego elementy w czasie pracy. Język UML składa się z szeregu różnego rodzaju diagramów związanych zarówno ze strukturą budowanego systemu, jak również jego zachowaniem. Sam standard UML jest niezwykle rozbudowany, obejmuję szereg zasad, kształtów itp. Z tego też powodu jest on świetnym narzędziem dla analityka, ale niekoniecznie dobrym narzędziem do komunikacji między członkami zespołu lub komunikacji z klientem.
Obecnie niewielu programistów, a nawet architektów zna wszystkie szczegóły standardu UML. Jest ku temu jakiś powód. Utrzymywanie dokumentacji tworzonej z pomocą UML’a jest kosztowne. Dopasowywania diagramu do aktualnej struktury systemu może być trudne i w efekcie stan dokumentacji z czasem ma niewiele wspólnego z aktualnym systemem.
Ponadto złożoność tego rodzaju diagramu nie robi z niego dobrego narzędzia do komunikacji między członkami zespołu. Tworzony model już na wejściu wymaga pewnej wiedzy technicznej. Są jednak pewne elementy diagramów UML, które przyjęły się bardzo dobrze:
diagramy przypadków użycia
diagramy klas tworzone jako reprezentacja konkretnego problemu lub wzorca projektowego
diagramy klas modelujące dziedzinę biznesową
diagramy stanów lub sekwencji dla konkretnych procesów biznesowych
UML definiuje również tzw. „component diagrams” i „deployment diagrams”, które z punktu widzenia architektury systemy będą dla nas najbardziej interesujące.
Figure 2 - https://cdn-images.visual-paradigm.com/guide/uml/what-is-component-diagram/02-component-diagram-overview.png
Diagramy komponentów obejmują elementy systemu o nieco większym poziomie abstrakcji niż klasy w kontekście języków obiektowych – zależnie od technologii możemy mówić tutaj o assembly, pakietach itd. Ten poziom pozwala nam zobrazować np. architekturę naszego kod w ramach aplikacji.
Figure 3 - https://modernanalyst.com/Portals/0/Public%20Uploads/customer_client_form.png
Deployments diagram dodatkowo obejmują elementy hardware’owe – serwery wraz z pewnym oznaczeniem komunikacji między elementami.
Bez wchodzenia w szczegóły możemy zauważyć:
Są dosyć „brzydkie” – oczywiście to bardzo subiektywne, ale musicie przyznać, że „brutalistyczna” forma diagramów przenosi nas nieco do lat 90.
Nie są proste. Notacja i zasady związane z tymi diagramami nie są oczywiste. Stworzenie lub interpretacja takiego diagramu bez wcześniejszego przygotowania może wcale nie być łatwa. Innymi słowy diagramy te nie mogę służyć jako uniwersalny element komunikacji i informacji na temat architektury systemu.
Nawet tutaj pewne elementy pozostają niejasne – np. strzałki między BankingClient – BankingServer. Czy komunikacja jest synchroniczna lub asynchroniczna? Itd.
Z pewnością diagramy UML są przydatne i mają swoje miejsce w procesie tworzenia oprogramowania. Chcielibyśmy jednak odnaleźć nieco prostszy system nadający się zarówno do sesji burzy mózgów, jak również późniejszej dokumentacji i komunikacji w zespole.
Model C4
Model C4 został zaproponowany przez Simon’a Brown’a (pozdrawiam 😊). Jest to dodatkowe narzędzie, które w przystępny sposób pozwala na wizualizację naszej architektury.
Model C4 bazuje na czterech poziomach abstrakcji. Możemy je sobie wyobrazić jako mapę, którą coraz bardziej przybliżamy. Na początku widzimy mapę z kropką reprezentującą całe miasto. Następnie schodzimy coraz niżej, aż do poziomu poszczególnych ulic. W podobny sposób patrzymy na architekturę naszych systemów. Przechodzimy od poziomu ogólnego do szczegółów.
Poszczególne poziomy modelu C4 (zaczynając od najbardziej ogólnego):
C1 – kontekst (ang. context)
Figure 4 - https://c4model.com/
To widok z lotu ptaka na cały nasz system. Widzimy tutaj głównie nasz system (reprezentowany jako pojedynczy element niezależnie od tego ile aplikacji obejmuje), aktorów zewnętrznych i systemy zewnętrzne z którymi się komunikujemy. W tym wypadku koncentrujemy się na otoczeniu naszego systemu. Nie wchodzimy w techniczne aspekty systemy. Nasz system może się wewnętrznie składać z wielu mniejszych elementów, które deploy’owane są osobno. Elementy, który tutaj widzimy to:
actors
software system
external systems
C2 – kontenery (ang. containers)
Figure 5 - https://c4model.com/
Widok C2 pozwala nam na skupieniu się na wewnętrznych elementach naszego systemu. Uwaga: słowo kontener nie ma tutaj nic wspólnego z Docker’em (chociaż oczywiście nasz system może go wykorzystywać).
Kontenerem może być aplikacji serwerowa, aplikacja webowa, baza danych itd.
Ważna zasada: generalnie kontener to aplikacja, która jest deploy’owana osobno (deployment unit – po angielsku termin ten brzmi znacznie lepiej). Abstrahujemy tutaj od tego czy np. obie aplikacje są uruchomione na jednym fizycznie serwerze. Dodatkowo na diagramie prezentujemy linie określającą komunikację między kontenerami.
Bardzo ważne jest, aby każdy element był jasno opisany. Może się to wydać redundantne, ale pamiętajmy, że osoby o różnym technicznym poziomie zaawansowania mogą wykorzystywać później nasz model. My też chcemy, aby stworzony model był dla nas jasny za miesiąc, rok itd.
Zerknijmy na strzałki reprezentujące komunikację między modułami. Warto zauważyć, że komunikacja między modułami często jest dwustronna. Mimo to na naszym diagramie większość strzałek ma grot umieszczony po jednej stronie. Pamiętajmy, że na diagramie chcemy zaznaczyć komunikacją uwzględniając to, który element inicjuje komunikację. Zazwyczaj komunikacji między dwoma kontenerami nie jest w pełni symetryczna. Jakiś element jest tutaj zazwyczaj bardziej aktywny lub bierny.
Na tym poziomie mamy:
actors
external systems
containers (można powiedzieć, że rozbiliśmy software system na kilka kontenerów)
C3 – komponenty (ang. components)
Figure 6 - https://c4model.com/
Diagram komponentów pozwala nam zerknąć „do środka” kontenerów i zobaczyć ich wewnętrzną strukturę. Odpowiednikiem tego diagramu mógłby być „Component diagram” z języka UML. To jakie elementy umieścić na diagramie zależy od nas. Ważne jest to, że nie musimy umieszczać absolutnie wszystkich elementów – w tym wypadku kontrolerów. Na diagramie umieszczamy kluczowe z punktu widzenia architektury elementy. Nie oznacza to, że np. opisywany powyżej system nie zawiera innych kontrolerów wewnątrz projektu API.
Elementy na diagramie:
actors
external systems
containers
components (rozbijamy dany kontener na komponenty, aby przedstawić ich wewnętrzną strukturę)
C4 – kod (np. diagram klas z UML’a) Na tym etapie właściwie zeszliśmy do poziomu kodu. Simon Brown poleca, aby w ogóle pominąć ten poziom. Dlaczego? Ponieważ na tym etapie jesteśmy na poziomie pojedynczych klas. Możemy oczywiście zbudować diagram klas i korzystać z innych elementów np. UML’a. Niestety tego typu dokumentacja jest mało przydatna dlatego, że bardzo szybko stanie się nieaktualna. Zazwyczaj utrzymywanie takiej dokumentacji w pełnej zgodności z kodem jest niezwykle pracochłonne i zwyczajnie się nie opłaca.
Podsumowanie - Więcej na temat modelu C4 Jak widać model C4 nie jest niczym skomplikowanym. Jego elementy odnajdziemy w innych modelach takich jak UML. Jego zaletą jest prostota i dosyć intuicyjny sposób budowania naszego modelu od widoku ogólnego do widoków coraz bardziej złożonych. Ta analogia jest zazwyczaj intuicyjna dla każdego członka zespołu.
Sam model C4 nie jest żadną nowością, ale wciąż często można napotkać zespołu, które o nim nie słyszały. Mam nadzieję, że ten krótki materiał okazał się przydatny.
Świetnym wprowadzeniem do modelu C4 jest prezentacja jej twórcy – Simona Browna, którą odnaleźć można na Youtube: https://www.youtube.com/watch?v=x2-rSnhpw0g https://c4model.com/
Jeśli znasz już te metody pracy napisz nam w komentarzu co o nich sądzisz.
Które podejście jest lepsze? Dla jakiego rodzaju projektów?
Zapraszamy do kolejnych artykułów!
Comments