Wakacje się skończyły. W plecakach miejsce konserw, survivalowych gadżetów i karimat, zajęły laptopy i niezbędniki do bytowania w biurowej dżungli. A gdybyś do plecaka miał spakować kod. Według jakich kryteriów wybierzesz to, co jest ci niezbędne do przeżycia? Jak skutecznie nadać priorytety poszczególnym modułom? Które elementy architektury pozytywnie przejdą selekcję, a które nie? Już za kilka akapitów znajdziesz praktyczną instrukcję.
Piszesz, myślisz, konsultujesz, piszesz i myślisz, usuwasz, piszesz itd itp. Wkładasz mnóstwo energii w odkrywanie zawiłości biznesowych otaczających twoją aplikację, a później w przelewanie tych prawidłowości w kod.
Wyobraź sobie teraz, że wydrukujesz kod całej swojej aplikacji i zamkniesz w archiwum. Wybucha pożar. Masz tylko standardowy 25 litrowy plecak 🎒. Więcej nie zabierzesz. Który fragment kodu ocalisz? Jesteś w stanie w 5 sekund powiedzieć „to ten kawałek”?
Kodzie, znaj swój priorytet
Moduł płatności jest ważniejszy niż moduł rekomendacji i poleceń. Płatność kartą kredytową jest pilniejsza niż płatność za pomocą eurogąbek (nie znasz? poszukaj pod hasłem “nasza klasa”). Wiesz to dzięki priorytetom. To one mówią nam, software developerom, czym zająć się w pierwszej kolejności, aby management był zadowolony, a stan konta rósł jak rzeżucha na Wielkanoc 🐣.
W projektach zwinnych priorytetem jest wysokość historyjki w backlogu lub na tablicy kanban.
Na zrzucie ekranu zauważyłeś pewnie słowo “problem”, w opisie każdego z priorytetów. W świeżutkich projektach raczej mamy do czynienia z wyzwaniami. Komplikacje czyli problemy pojawiają się, gdy dodamy kontekst utrzymania: bugfixing i rozbudowę istniejących aplikacji.
Triage
W ratownictwie medycznym jest stosowana procedura, mająca zapewnić przeżycie jak największej liczbie poszkodowanych.
System segregacji nosi nazwę S.T.A.R.T. (Simple – prosta, Triage – selekcja, And – i, Rapid – szybka, Treatment – pomoc) i prowadzi do przypisania jednego z czterech kolorów:
- czarny – nie do uratowania.
- czerwony – zająć się w pierwszej kolejności,
- żółty – zająć się w drugiej kolejności,
- zielony – może poczekać.
Krótki przerywnik. Przyznaj się, ile aplikacji czy modułów popełniłeś, które opiszesz kolorem “czarny” i nie da się już ich uratować? 💀 Takich, których nie chcesz rozwijać, mimo położonego na stół worka złota. Policz wszystkie zawiłe i niezrozumiałe kody. Funkcje ciągnące się przez ekran jak karty encyklopedii. Wieżowce utworzone z pętli IF z poprzeplatanymi zmiennymi. Właśnie takiego kodu chcemy unikać. Aby nigdy więcej go nie popełniać, musimy być świadomi, które moduły wymagają największej uwagi.
Czerwony, żółty, zielony
Spróbujmy podzielić kod aplikacji kierując się triage. Zgodzisz się z poniższą kategoryzacją?
- Czerwony – domena. Encje i przypadki użycia. Warstwa, której kod zdecydowanie powstaje w wyniku ciężkiej pracy opartej na wiedzy. Okupiony godzinami spotkań i konsultacji i litrami kawy.
- Żółty – technikalia istotne. Aplikacyjne reguły autoryzacji i zarządzanie sesją, routing kontrolerów. Tu trafi też kod, będący następstwem działań optymalizacyjnych.
- Zielony – technikalia dekoracyjne. Okruszki, które łączą gotowe frameworki i biblioteki z naszym kodem. Czyli klaski typu MySqlDriver, biblioteka loggera, kod własny frameworka.
Triage w architekturze
Spójrz na poniższy obrazek. W odniesieniu do kodu, triage (czerwony-żółty-zielony) to nic innego jak granice rozdzielające warstwy architektoniczne.
Aby chronić to co jest ważne, musisz wyraźnie widzieć te granice. Nie dopuszczaj do sytuacji, w której cała baza kodu, splątana jak hybryda lasagne i spaghetti, zostanie przydzielona do kategorii czarny – nie do uratowania.
Wracając do analogii pożaru. W plecaku masz ograniczone miejsce, jeśli wpakujesz tam zbędne implementacje i komponenty, to te krytyczne nie przeżyją.
Stosowanie triage’u
Czy powinieneś z niego korzystać tylko w sytuacjach wyjątkowych? Nie – musisz ich używać z każdą wprowadzaną linijką kodu.
W cyklu życia projektów IT pojawiają się magiczne siły, które przeciągają nasz kod na ciemną (czarną) stronę mocy. Prowadzą do stanu, w którym krytyczne fragmenty są przygniatane zbędnymi wstawkami. Zrastają się z powłokami adapterów i niskopoziomowych implementacji. Taki kod śmiało możesz zhashtagować: #if-bo-termin-goni, #insert-w-kontrolerze, #tdd-nie-da-sie.
Dlatego bądź czujny i nie daj się przeciągnąć na złą ścieżkę. 🧐
Jaką wartość ma to, co znajduje się poza granicą domeny?
Trzymając się naszej analogii. Plecak był za mały. Wyniosłeś z pożaru tylko domenę i interfejsy dla dalszych warstw. Straciłeś mnóstwo przydatnego, praktycznie działającego kodu, ale czy bezpowrotnie?
W boczną kieszeń plecaka wpakowałeś interfejsy definiujące komunikację z bazą danych. Opłakując utracony kod sięgasz do kieszeni. Co z niej wyciągasz? Instrukcję, jak odbudować zjarane warstwy swojej aplikacji. Krok po kroku, zgodnie z wymaganiami domeny. Z interfejsów odtworzysz też testy jednostkowe. Wtedy cała reszta to tylko dopisanie paru linijek kodu w ciałach metod żółto-zielonych.
Co spakujesz do plecaka?
Jako autorzy bronimy naszych dzieł. Każdego napisanego wiersza kodu. Ale wiemy, powinniśmy wiedzieć, które fragmenty są krytyczne, a które mniej ważne.
A gdzie tu pożar? Gonią nas terminy. Czas jest towarem deficytowym. Prędzej czy później popełnimy jakieś szybkozłączki i tymczasowe protezy “byle działało”. Ważne, abyśmy robili to świadomie, nie naruszając domeny.
Drugim przykładem jest code review. Patrzysz na listę pull requestów. Chciałbyś wszystko skrupulatnie przejrzeć i posłużyć, jak wujek Bob, dobrą radą. Nie sprawdzisz jednak wszystkiego, bo braknie Ci czasu. Wtedy zdrowy rozsądek i minimalizm powinien kierować Cię w jedno miejsce – domena. Zatem: wydziel tę warstwę i skup się na niej!
I tu wkracza, cała na biało, czysta architektura,🦄 dzięki której skutecznie zorganizujesz swój kod.
Zobacz jak wykorzystać czystą architekturę
- w praktyce, w Python
- wydzielając encje domenowe i separując logikę biznesową
- pochłaniając wiedzę z serii artykułów Grześka