Szperałem w sieci szukając informacji o architekturze i microservisach, a wpadłem na to:

… communication between two different software modules is proportional to the communication between the designers and developers of these modules. Conway?s law exposes the vulnerability in monoliths as they grow in size. Micro-services may not be the best, but better than monoliths for the contemporary web based applications. (Źródło: Micro-Services: A comparison with Monoliths | My Blog)

To “prawo” wyjaśnia dlaczego powstają złe interfejsy a nawet zła architektura: z reguły dlatego, że to – architektura – jest lepszym lub gorszym kompromisem pomiędzy zespołami programistów, ich obciążenia, krótkich terminów itp. Obserwuję to dość często w organizacji pracy developerów.

Jednak, żeby powstała taka “dobra architektura”, ktoś “ponad zespołem developerów” powinien zaprojektować architekturę: komponenty z ich odpowiedzialnościami i interfejsy między nimi.

Typowym problemem jaki napotykam, nie tylko w dużych projektach dla “budżetówki”, jest architektura będąca efektem przepychanek, polityki, walki o “mendejsy”, czyli o to który dostawca  (albo wewnętrzny zespół) dostanie większy budżet. To najgorsze i niestety nie raz spotykane metody budowy architektury.

Jak to robić dobrze? Idąc za Fowlerem, podstawą budowy (ustalania) granicy odpowiedzialności komponentu jest “granica kontekstu”. Można to przedstawić tak:

Powyżej pokazano wynik analizy, mamy tu model pojęciowy. Widać, że pewne pojęcia (docelowo klasy, ich operacje i atrybuty) są dość gęsto powiązane, inne luźno. Granice pomiędzy komponentami  powinno budować się tak, by silnie powiązane elementy były w jednym komponencie (nigdy nie rozdzielaj rodziny) a interfejsy między nimi były jak najprostsze. Stosowanie DTO oznacza, że komponent powinien jednorazowo zażądać całego agregatu danych (dokumentu) i samemu skorzystać, nawet tylko z części danych które dostał, zamiast detalicznie prosić o poszczególne pola. Innymi słowy niezależnie od tego czy w danym momencie potrzebujemy tylko wartości konkretnej faktury, danych nabywcy czy faktycznie całej jej zawartości, zawsze żądamy całej faktury. Dzięki temu interfejs (API) jest prostsze, liczba wywołań API jest zawsze mała. Powyższy przypadek zaowocuje poniższym podziałem na komponenty:

ModelDziedzinyGraniceKontekstuKomponentu

Metoda ta i podejście (jako dobra praktyka), i u Fowlera (cytowany DTO) i u Evansa (autor wzorca Domain Driven Design) nazywana jest “bounded context” (granica kontekstu, rodzina zawsze razem i tylko jedna rodzina w jednym mieszkaniu). Dzięki temu uzyskujemy bardzo dobry, przy okazji zgodny z zasadą “[[Open Close Pryncypia]]”, model architektury, który pozwala zlecić komponenty do wykonania, definiując wyłącznie opracowane już interfejsy, kolejność ich (komponentów) wykonania nie ma znaczenia dla całości.

Przy okazji ujawnia się “zło” jakie wyrządza budowanie złożonego oprogramowania na bazie integracji poprzez współdzielenie danych:

ModelDziedzinyIntegracjaPrzezWspoldzielnieDanych

Komponenty są silnie od siebie uzależnione (współdzielona baza danych w modelu relacyjnym), nie da się tworzyć (kodować) tych komponentów niezależnie od siebie, bo trzeba uzgadniać a potem uznać, wspólny model danych. Ingerencja w jakikolwiek komponent z reguły oznacza ingerencję w całą aplikację.

Dzieląc system na niezależne komponenty (każdy komponent sam zarządza swoimi danymi) , ustalamy integrację z użyciem interfejsów a nie współdzieląc dane, z czego całkowicie rezygnujemy:

ModelDziedzinyWspolpracaKomponentowDziedzinowych


To jest powód dla którego, w dobrych firmach developerskich kluczową rolę pełni architekt. Na poziomie logiki biznesowej, w zasadzie jest nim – takim architektem – analityk biznesowy-projektant, który po zakończeniu etapu analizy i projektowania, pełni rolę “[[product ownera]]”, prowadzącego nadzór autorski i zarządzanie zmianą wymagań.

Tak więc architektura powinna być efektem głębokiej analizy i projektowania z testami, dopiero potem powinna się stać – być może każdy komponent osobno – materiałem do zlecenia dla developerów. Najgorszy wariant to podział na komponenty z pomocą negocjacji, polityki i walki o budżet. 

Jarosław Żeliński

Jarosław Żeliński: Od roku 1991 roku, nieprzerwanie, realizuje projekty z zakresu analiz i projektowania systemów, dla urzędów, firm i organizacji. Od 1998 roku prowadzi samodzielne studia i prace badawcze z obszaru analizy systemowej i modelowania (modele jako przedmiot badań: ORCID). Od 2005 roku, jako wykładowca akademicki wizytujący (nieetatowy), prowadzi wykłady i laboratoria (ontologie i modelowanie systemów informacyjnych, aktualnie w Wyższej Szkole Informatyki Stosowanej i Zarządzania pod auspicjami Polskiej Akademii Nauk w Warszawie.) Oświadczenia: moje badania i publikacje nie mają finansowania z zewnątrz, jako ich autor deklaruję brak konfliktu interesów. Prawa autorskie: Zgodnie z art. 25 ust. 1 pkt. 1) lit. b) ustawy o prawie autorskim i prawach pokrewnych zastrzegam, że dalsze rozpowszechnianie artykułów publikowanych w niniejszym serwisie jest zabronione bez indywidualnej zgody autora (patrz Polityki Strony). Konsultacje: wszelka pomoc i wyjaśnienia dotyczące treści artykułów autora bloga udzielana jest wyłącznie w ramach płatnych konsultacji.