Jak zostać architektem oprogramowania?

Aby projektować dobrą architekturę oprogramowania trzeba najpierw zaznajomić się z jej przesłankami, rodzajami, a także sposobami wdrażania. Architektura nie jest przecież czymś stałym, co wszędzie implementowane jest w jednakowy sposób.


Architektura oprogramowania

Poruszane dzisiaj zagadnienie nie jest terminem posiadającym sztywną definicję. Dzieje się tak, ponieważ architektura oprogramowania dzieli się na kilka grup, w różnych zakresach. Jednak ogólnie rzecz biorąc architektura oprogramowania to sposób na zorganizowanie systemu, środowiska, jego elementów oraz komunikacji pomiędzy nimi. Jednym z podziałów architektury, który możemy wyodrębnić jest podział ze względu na tzw. "głębokość" i to na nim się dzisiaj skupimy. Wyróżnić możemy trzy poziomy architektury w tym podziale: poziom przedsiębiorstwa, systemu oraz aplikacji. W tym wpisie wejdziemy głębiej w tematykę dwóch ostatnich, czyli architektury aplikacyjnej oraz systemowej.


Dlaczego architektura oprogramowania jest potrzebna?

Zanim przejdę do "mięsa" dzisiejszego wpisu, muszę powiedzieć trochę o tym dlaczego projektowanie architektury jest bardzo ważne. Wszyscy chyba zgodzą się ze mną, że etat dla architekta w systemie klasy CRUD będzie zbędny, jednak co w sytuacji kiedy nasz system jest trochę większy? Wyobraźmy sobie 20 programistów i programistek pracujących nad nowym, bardzo innowacyjnym systemem e-commerce. Zdaję sobie sprawę, że w internecie znajdziemy mnóstwo pomysłów na rozwiązanie takiego problemu, jednak załóżmy, że nasz system jest bardzo innowacyjny i potrzebujemy nowy produkt (heheszki z e-commerce'ów). Potrafisz wyobrazić sobie ten chaos kiedy Ci wszyscy programiści rzucą się do burzy mózgów? Zaczną się propozycje w stylu: "robimy mikroserwisy", "słyszałem, że DDD jest fajne", "rok temu na konferencji usłyszałem, że nie robi się już mikroserwisów tylko modularne monolity", "użyjmy modnego graph ql". Masz może flashbacki? Ja niestety mam. Systemy "projektowane" w ten sposób to tykające bomby. 

Dobieranie rozwiązań programistycznych na zasadzie wyboru tych modnych, zazwyczaj kończy się failem. Poprzedźmy development o miarodajny planning oraz analizę, z których wyniknie klasa złożoności naszego problemu, a do której dopasujemy styl programistyczny czy architektoniczny. Zacznijmy analizować i projektować tak, aby dobierać rozwiązanie do problemu, a nie na odwrót. I to jest właśnie zadanie architekta oprogramowania, aby zaprojektować coś, co później programiści wdrożą zgodnie z założeniami. Jednak czy można robić to bez architekta? Pewnie, że można, lecz wtedy zespół potrzebuje solidnego tech lead-a, który weźmie na siebie obowiązek projektowania i podejmowania decyzji architektonicznych.

Jak robi się architekturę?

Odpowiedź na to pytanie nie jest trudna, jest długa. Jak już wcześniej wspomniałem architektura to nie jest tylko wybór wzorców projektowych, sposobu modularyzacji czy technologii. W głównej mierze jest to zadanie wyboru konkretnych rozwiązań, ale na podstawie wiedzy o systemie, który chcemy zaprojektować. Przejdźmy teraz przez jedne z najważniejszych, ogólnych etapów tworzenia architektury systemu. 
  1. Swoją przygodę z projektowaniem architektury powinniśmy rozpocząć od poznania biznesu. Odkrycie jego procesów, domen, nałożenie bounded contextów, a także zrozumienia celu oprogramowania, które ma powstać lub już istnieje. Metod odkrywania biznesu jest bardzo wiele, lecz gorąco polecam Event Storming, który pozwala na łatwe modelowanie systemu na każdym poziomie. 
  2. Stosując ES w połączeniu z Domain Driven Design odkryjemy wiele czynników architektonicznych motywujących nasze późniejsze wybory, a także częściowo zaprojektujemy nasz system. Architectural drivers to zbiór wymagań, wyzwań czy warunków, które muszą zostać uwzględnione podczas tworzenia architektury. Przykładowo, nasz system może wymagać dużej szybkości zapisu danych, ale niekoniecznie ich spójności, co prawdopodobnie determinować będzie użycie bazy nierelacyjnej.
  3. Posiadając wiedzę o biznesie, który stoi za oprogramowaniem oraz wymagania i jego środowisko, możemy zacząć podejmować decyzje architektoniczne. Architectural decision records to zbiór decyzji, jakie podjęliśmy lub podejmiemy (zbiór decyzji, który żyje zawsze i zawsze powinien być aktualny!) uwzględniając zagrożenia, wymagania i inne drivery architektoniczne poznane podczas odkrywania biznesu. 
  4. Rozumiejąc zagrożenia, wymagania jakości i posiadając już pewne podjęte decyzje, możemy przejść do projektowania oprogramowania. Musimy uwzględnić tutaj wszystko czego dowiedzieliśmy się do tej pory, a następnie przekuć to w gotowy plan systemu. Pomocne będą tutaj wyniki sesji Event Stormingowych połączonych z DDD. Udzielą nam one informacji na temat modułów i sposobu interakcji pomiędzy nimi. Poznamy reguły i niezmienniki domenowe zagnieżdżone w odkrytych procesach, co pozwoli nam na ich implementację. To tutaj musimy podjąć decyzje o tym, jaką architekturę systemową i aplikacyjną powinniśmy wybrać. Całość wypada uwiecznić, tak, aby możliwy był powrót do naszej wizji. Może to być UML, własna notacja lub coś, co już istnieje i doskonale się do tego nada: model wizualizacji architektury C4 (context, container, component, code).
  5. Nadzór i pomocna dłoń dla zespołów wykonujących "prace rzemieślnicze" czyli tzw. technical leadership. Konieczna jest kontrola procesu wdrażania systemu, a także korygowanie wizji o pojawiające się w trakcie implementacji nowe drivery architektoniczne. 

Architektura systemowa

Zgodnie z obietnicą ze wstępu, spróbuje teraz wskazać różnice pomiędzy dwoma najgłębszymi rodzajami architektury. Na początek weźmy na tapet architekturę systemową. Tak, jak wspomniałem wcześniej, jest to wysoki poziom abstrakcji systemu opisujący jego kształt, środowisko i sposoby komunikacji w obrębie nadgrup funkcjonalnych. Architekturą systemową nazywać będziemy więc sposób w jaki zorganizujemy wspomniane aspekty w naszym oprogramowaniu. Większość z nas zapewne słyszała takie terminy jak: mikroserwisy, modularne monolity czy monolity. Są to właśnie rodzaje architektury systemowej, o których powiem w przyszłości, jednak aby nie zostawić Cię bez pewnej dawki wiedzy, spróbuję po krótce przejść po najpopularniejszych rodzajach architektury systemowej.

Architektura aplikacyjna

Czymś, co wchodzi w skład modułów, serwisów czy całej instancji systemu jest architektura aplikacyjna. Określa ona strukturę i logiczny sposób działania mechanizmów w obrębie danej grupy. W przypadku SOA, grupą tą będą poszczególne usługi, które mogą implementować inną architekturę aplikacyjną. Podobnie będzie w przypadku modularnego monolitu, gdzie moduły mogą używać innych struktur. W przypadku monolitu, całe wnętrze określać będzie jeden typ architektury aplikacyjnej. Jak się pewnie domyślasz istnieje wiele typów takiej architektury. O nich również opowiem w przyszłych wpisach, jednak tak, jak poprzednio, przejdźmy teraz przez kilka popularnych rodzai architektury aplikacyjnej.

Podsumowanie




Polecane wpisy:

KISS: keep it simple, stupid!

Zasada KISS: "Keep it simple, stupid", może zostać dosłownie przetłumaczona na: "rób to prosto, głupku". Mówi ona o tym, abyśmy tworzyli kod w jak najprostszy i najbardziej czytelny sposób. Już dziś sprawdź, czego się wystrzegać, aby spełniać KISS.

Sprawdź ten wpis

Wzorce projektowe

Wzorce projektowe zostały stworzone po to, aby nie wymyślać przysłowiowego koła na nowo. Znajomość wzorców projektowych i umiejętność ich stosowania pozwala na szybkie rozwiązywanie problemów. Wpis ten radzi, jakie wzorce zastosować u siebie.

Sprawdź ten wpis

Wzorzec singleton

Kolejny kreacyjny wzorzec projektowy omawiany na łamach tego bloga: singleton. Wzorzec dookoła którego narosło wiele mitów i legend. Dziś o tym dlaczego singleton jest antywzorcem, jakie problemy powoduje oraz kiedy warto po niego sięgnąć.

Sprawdź ten wpis

Wzorzec stan (state)

Dziś prezentuję kolejny wzorzec projektowy, który pozwala uniknąć drabinek if-else if. Mowa tutaj o wzorcu state, który idealnie nada się, jeśli posiadasz różne stany w swoim systemie oraz chcesz mieć możliwość płynnego przechodzenia pomiędzy nimi.

Sprawdź ten wpis

Wzorzec pełnomocnik (virtual proxy)

Wzorzec virtual proxy służy do tworzenia obiektów pośrednich, które nadzorują dostęp do obiektów dla których są pełnomocnikami. Dzięki temu, że pełnomocnik i klasa bazowa udostępniają jednakowy interfejs, możemy ukryć w pośredniku dodatkową logikę.

Sprawdź ten wpis

Autor wpisu:

Gabriel Ślawski

Fanatyk czystego i prostego kodu. Zwolennik podejść DDD oraz Modular Monolith. Na codzień pracuje jako programista i architekt. Po godzinach spełnia się w projektach open source, udziela się na blogach oraz czyta książki o kosmosie i astrofizyce.