Wprowadzenie
Wpis na LinkedIn:
GUI czy DSL, klikanie czy tekst? Co wybierzesz do modelowania?
Structurizr ma swój DSL, za pomocą którego opisywana jest architektura a następnie generowane są odpowiednie widoki C4. Text to Model.
Z drugiej strony możemy zamodelować strukturę bazy danych w LucidChart albo Miro klikając w GUI. Click to Model.
Jeśli mógłbyś wybrać, to którą z tych opcji preferowałbyś do modelowania i dlaczego?
Jako devsi jesteśmy przyzwyczajeni do kodowania, stąd DLS structurizra jest dla nas czymś naturalnym. Jedynym problemem jest to, że trzeba się go nauczyć. Tego problemu nie ma w przypadku GUI. Ale znowu GUI cierpi z UX gdy dodawane są kontrolki manipulujące elementami (dodaj, usuń, zmień nazwę).
Ja osobiście wolę DSL nawet jeśli potrzebuje czasu by się go nauczyć, ze względu na prostotę podglądu wygenerowanego na podstawie tekstu.
Deweloperzy często deklarują: “my wszystko dokumentujemy w modelach C4 a nie w UML, którego deweloper nie używa!” Problem?
UML to język a Model C4 to wzorzec architektoniczny, i to dość ogólny. Na diagramie poniżej Model C4 (szablon). Kluczowe pytanie: który deweloper dostarcza dokumentację na poziomie 3 i 4, a to tam jest logika biznesowa (kod podzielony na komponenty)?
Wśród deweloperów popularne są MIRO, draw.io (GUI) czy PlantUML (DSL). Tymczasem Simon Brown , pomysłodawca C4 pisze:
Jako branża preferujemy tworzenie diagramów (np. hashtag#Visio, #draw.io, hashtag#Lucidchart, hashtag#PlantUML, hashtag#Mermaid itp.) zamiast modelowania (np. Sparx EA, Archi, IcePanel, Structurizr itp.), głównie dlatego, że bariera wejścia jest stosunkowo niska i jest postrzegana jako znacznie prostsze zadanie. Istnieje jednak kilka poważnych problemów związanych z używaniem tych narzędzi do tworzenia diagramów architektury oprogramowania…
A w jednej z wielu swoich prezentacji (https://www.youtube.com/watch?v=gNj8I4uSTgc&t=1016s) odradza nieformalne szkice i diagramy i zaleca jednak notację UML bo jest ona powszechnym standardem.
Model C4
C4 to czteropoziomowy, prosty model dokumentowania architektury całego systemu . Opracował go Simon Brown (https://simonbrown.je/) autor książki Software architecture for developers . Dostępny jest także wywiad z Robertem Blumen (SalesForce Desk.com) opublikowany pod tym samym tyłem . Publikacji naukowych na temat modelu C4 jest bardzo mało i wspominają one C4 przy okazji (Google Scholar pokazuje 1200 w dniu pisania tego tekstu, to śladowe ilości). Model ten jest głównie wymieniany jako jedno z narzędzi. Dostępną publikacją poświęconą samemu modeli jest np. C4 model in a Software Engineering subject to ease the comprehension of UML and the software development process . Mimo, że publikacji na temat modelu C4 jest mało, zdobył sobie dość dużą popularność za sprawą prostoty i łatwości szkicowania .
Simon pisze:
Aby stworzyć “mapy kodu”, potrzebujemy najpierw wspólnego zestawu abstrakcji, których możemy użyć do opisania statycznej struktury systemu oprogramowania. W modelu C4:
System oprogramowania składa się z jednego lub więcej kontenerów (aplikacji i magazynów danych), z których każdy zawiera jeden lub więcej komponentów, które z kolei są implementowane przez jeden lub więcej elementów kodu (klasy, interfejsy, obiekty, funkcje itp.). A ludzie (aktorzy, role, personas, nazwane osoby itp.) używają systemów oprogramowania, które tworzymy.
Co zobrazował:
Software System (C1)
Brown definiuje go jako (https://c4model.com/abstractions/software-system):
System oprogramowania jest najwyższym poziomem abstrakcji i opisuje coś, co dostarcza wartość swoim użytkownikom, niezależnie od tego, czy są ludźmi, czy nie. Obejmuje to modelowany system oprogramowania i inne systemy oprogramowania, od których zależy system oprogramowania (lub odwrotnie).
Jednak sam przyznaje, że:
Niestety termin “system oprogramowania” jest najtrudniejszą do zdefiniowania abstrakcją modelu C4, a nie pomaga w tym fakt, że każda organizacja będzie miała również własną terminologię do opisania tego samego, zwykle używając terminów takich jak “aplikacja”, “produkt”, “usługa” itp.
Generalnie definicja tego bytu jest dość mętna. Osobiście uważam, że najbliższe są tu pojęcia “aplikacja” lub “produkt”, które oznaczają coś samodzielnego, dostarczanego przez jeden podmiot. W języku polskim aplikacja to : komputerowy program użytkowy (SJP).
Przykład:
Container (C2)
Definiownay jest jako (https://c4model.com/abstractions/container):
Nie Docker! W modelu C4 kontener reprezentuje aplikację lub magazyn danych. Kontener jest czymś, co musi być uruchomione, aby cały system oprogramowania działał.
Pierwszy zgrzyt: to także aplikacja? I czym tu jest “cały system” na tle tego czym jest C1? Przykłąd:
Component (C3)
Tu dla odmiany mamy (https://c4model.com/abstractions/component):
Słowo “komponent” jest bardzo przeciążonym terminem w branży tworzenia oprogramowania, ale w modelu C4 komponent jest grupą powiązanych funkcjonalności zamkniętych za dobrze zdefiniowanym interfejsem. Jeśli używasz języka takiego jak Java lub C#, najprostszym sposobem myślenia o komponencie jest to, że jest to zbiór klas implementacji za interfejsem.
Tu mamy definicję podobną do tej z UML: jest to zbiór klas implementacji za interfejsem. Co prawda nie wiadomo co łączy owe “powiązane funkcjonalności”, ale definicja sama z siebie jest jasna. To można nazwać poziomem HLD aplikacji (komponenty). Przykład:
Code (c4)
Na samym końcu mamy (https://c4model.com/abstractions/code):
Wreszcie, komponenty składają się z jednego lub więcej elementów kodu zbudowanych z podstawowych elementów składowych używanego języka programowania – klas, interfejsów, wyliczeń, funkcji, obiektów itp.
Można to nazwać poziom LLD aplikacji (wewnętrzna budowa komponentów). Przykład:

Co do złudzenia przypomina diagram klas (i de facto jest nim: to są klasy i związki użycia).
Dynamika systemu
Brown pisze (https://c4model.com/diagrams/dynamic):
Diagram dynamiczny może być przydatny, gdy chcesz pokazać, jak elementy w modelu statycznym współpracują w czasie wykonywania, aby wdrożyć historię użytkownika, przypadek użycia, funkcję itp. Ten dynamiczny diagram jest oparty na diagramie komunikacji UML (wcześniej znanym jako “diagram współpracy UML”). Jest on podobny do diagramu sekwencji UML, chociaż pozwala na dowolne rozmieszczenie elementów diagramu z ponumerowanymi interakcjami w celu wskazania kolejności.
I podaje przykład:
Diagram wdrożenia
I znowu autor przywołuje UML (https://c4model.com/diagrams/deployment):
Diagram wdrażania pozwala zilustrować, w jaki sposób instancje systemów oprogramowania i/lub kontenerów w modelu statycznym są wdrażane w infrastrukturze w danym środowisku wdrażania (np. produkcyjnym, przejściowym, deweloperskim itp.). Jest on oparty na diagramie wdrożenia UML.
Przykład:
Podsumowanie modelu C4
Gdy pierwszy raz usłyszałem o C4 od deweloperów nie lubiących UML, ucieszyłem się, że zaczęli projektować. Jednak modele te tworzone są dopiero po tym, jak “kod zadziała”, i z reguły tworzona jest dokumentacja powykonawcza dwóch górnych poziomów. W użyciu są najczęściej proste obrazkowe i bardzo pracochłonne narzędzia, wymienione na początku tego tekst, co sam Simon komentuje tak:
Jako branża preferujemy tworzenie diagramów (np. Visio, draw.io, Lucidchart, PlantUML, Mermaid itp.) zamiast modelowania (np. Sparx EA, Archi, IcePanel, Structurizr itp.), głównie dlatego, że bariera wejścia jest stosunkowo niska i jest postrzegana jako znacznie prostsze zadanie. Istnieje jednak kilka poważnych problemów związanych z używaniem narzędzi do tworzenia diagramów architektury oprogramowania: nie mogą udzielić żadnej pomocy ani zweryfikować twoich diagramów,
nie można wysyłać zapytań do diagramów (np. “pokaż mi wszystkie zależności komponentu X”). (https://c4model.com/tooling)
Natomiast używając narzędzi do modelowania:
…tworzysz niewizualny model architektury oprogramowania (pojedynczą definicję wszystkich elementów i relacji między nimi), a następnie tworzysz różne widoki (które stają się diagramami) na tym modelu. Wymaga to nieco więcej rygoru, ale problemy można rozwiązać – narzędzia do modelowania mogą zrozumieć semantykę tego, co próbujesz zrobić, zapewnić dodatkową pomoc, a zmiana nazw elementów / relacji jest łatwa. Modele architektury oprogramowania są zasadniczo tylko skierowanymi grafami, składającymi się z węzłów i krawędzi, z diagramami pokazującymi podzbiór grafu. (https://c4model.com/tooling)
Jak to wygląda z użyciem UML i narzędzi CASE
Poziom C1, Software System to kontekst. Simon pisze:
Diagram kontekstu systemu jest dobrym punktem wyjścia do tworzenia diagramów i dokumentowania systemu oprogramowania, umożliwiając cofnięcie się i zobaczenie szerszej perspektywy. Narysuj diagram przedstawiający system jako pudełko w centrum, otoczone przez użytkowników i inne systemy, z którymi wchodzi w interakcje. (https://c4model.com/diagrams/system-context)

Poziom C2, kontenery:
Po zrozumieniu, w jaki sposób system pasuje do ogólnego środowiska IT, bardzo przydatnym kolejnym krokiem jest przybliżenie granic systemu za pomocą diagramu kontenera. “Kontener” to coś w rodzaju aplikacji internetowej po stronie serwera, aplikacji jednostronicowej, aplikacji komputerowej, aplikacji mobilnej, schematu bazy danych, systemu plików itp. Zasadniczo kontener jest oddzielnie uruchamialną/wdrażalną jednostką (np. oddzielną przestrzenią procesów), która wykonuje kod lub przechowuje dane. (https://c4model.com/diagrams/container)
Przykład:

Poziom C3, komponenty:
Następnie możesz powiększyć i rozłożyć każdy pojemnik dalej, aby zidentyfikować główne strukturalne bloki konstrukcyjne i ich interakcje. Diagram komponentów pokazuje, w jaki sposób kontener składa się z szeregu “komponentów”, czym jest każdy z tych komponentów, jakie są ich obowiązki oraz szczegóły dotyczące technologii/wdrożenia. (https://c4model.com/diagrams/component)
Przykład:

Poziom C4, kod
Wreszcie, można powiększyć każdy komponent, aby pokazać, jak jest on zaimplementowany jako kod; przy użyciu diagramów klas UML, diagramów relacji encji lub podobnych. (https://c4model.com/diagrams/code)
Tu już klasyka UML:

Dynamika systemu:

Jednak używając narzędzi do modelowania (CASE) otrzymujemy walidowalny model całości systemu, łatwy do użycia i do aktualizacji. W narzędziu CASE takie modele, jako całość w powstają w kilka godzin a ich aktualizacja zajmuje minuty.
Podsumowanie
Tak więc w zasadzie Model C4 niczego nowego nie wnosi. Wielu ludziom dał ułudę, że to “dokumentacja”. Brown dostrzega jednak ten problem: niesformalizowane schematy blokowe w draw.io czy Plant UML są nadal pracochłonne i nie pozwalają na ich walidację, narzędzia CASE są tu znacznie lepsze.
Po co powstaje projekt i jego dokumentacja? By kod powstał szybciej i by nie trzeba było go czytać by zrozumieć jak działa cała aplikacja.
Paradoksalnie opracowanie modelu (kilku czytelnych, powiązanych logicznie diagramów) architektury na poziomie C3 czy C4 zajmuje np. w Visual-Paradigm góra kilka kwadransów a ich aktualizowanie to minuty. Np. w draw.io czy PlantUML ich tworzenie trwa kilkadziesiąt godzin, ich aktualizacja tyle samo!
Więcej na temat architektury HLD i LLD (tu poziom C3 iC4) w poście Modelowanie architektury HLD i LLD usług aplikacji – modelowanie podsystemów.
Simon Brown pisze o poziomie czwartym czyli o dokumentowaniu kodu:
Jest to opcjonalny poziom szczegółowości, często dostępny na żądanie w narzędziach takich jak IDE. Najlepiej byłoby, gdyby ten diagram był generowany automatycznie przy użyciu narzędzi (np. IDE lub narzędzia do modelowania UML) i należy rozważyć pokazanie tylko tych atrybutów i metod, które pozwalają opowiedzieć historię, którą chcesz opowiedzieć. Ten poziom szczegółowości nie jest zalecany dla niczego poza najważniejszymi lub złożonymi komponentami. (https://c4model.com/diagrams/code)
Czym niestety potwierdza to co przypuszczałem: dla niego dokumentacja to prace “powykonawcze”, a cytowana dyskusja na LinkedIn potwierdza jego podejście: najpierw żmudnie kodujemy a potem, ewentualnie, coś opiszemy. Miło jednak, że jako deweloper, na wielu konferencjach, dostrzega zalety standaryzacji (używanie UML) i dostrzega problem stosowania prostych obrazków i narzędzi takich jak draw.io czy PlantUML.
Model C4 to prosty sposób na dokumentowanie stosu technologicznego, czyli tego co w architekturze heksagonalnej nazywamy środowiskiem. Jak pokazuje praktyka, z reguły nie ma to nic wspólnego z udokumentowaniem najważniejszej rzeczy: logiki biznesowej. Nadal mamy jedynie stos technologiczny i jego prostą powykonawczą dokumentację, oraz nic w obszarze najważniejszym: JAK TO DZIAŁA.
Model C4 rozwiązuje może lokalne kwestie administracyjne ale żadnych innych. Niestety też, bardzo często, te niesformalizowane schematy są zrozumiałe jedynie dla ich autora. Właśnie mam przed sobą “dokumentację integracji” otrzymaną od pewnej dużej i znanej firmy, i niestety bez telefonu do jej autora jest ona bezwartościowa.