Przyczyny zjawiska technical debt

Nie ma róży bez kolców. Nie ma też znienawidzonego “technical debt“, bez popełnionych błędów. Nawet, jeśli wydawało nam się, że są one nieistotne.

 

Dług czyli debt

Zdefiniowaliśmy już dług technologiczny, jako “ukryty koszt przyszłych prac”. Zaciągamy go, gdy robimy coś teraz “na szybko”, chociaż wiemy, że przez to poświęcimy więcej czasu w przyszłości.

Wiemy czym jest technical debt i rozumiemy też, że nie musi być on zły, bo może nam dać przewagę w postaci możliwej tańszej zmiany wymagań. Coś, co zrobiliśmy “po łebkach” może okazać się wystarczające albo nawet zbędne. Oszczędzimy więc sobie wysiłku nie realizując od razu rozwiązania docelowego.

O ile pojęcie długu możemy rozumieć pozytywnie lub negatywnie, o tyle już same przyczyny powstania są już jednoznacznie negatywne. Musiało się przecież wydarzyć coś, co miało wpływ na nasze decyzje o realizacji rozwiązania, delikatnie mówiąc, odległego od ideału. Zwykle będziemy zasłaniać się brakiem wystarczającej ilości czasu, a czasami sięgniemy po argumenty bardziej skomplikowane, jak np. brak wystarczającej wiedzy w zakresie technologii, w której przyszło nam pracować.

Pisząc o przyczynach powstania technical debt wspomnieliśmy o MVP, restrykcyjnym Definition od Done czy odkładaniu na później wymagań niefunkcjonalnych. Tymczasem przyczyn powstania długu technologicznego jest o wiele więcej…

 

Jak powstaje dług?

Jakiś czas temu, podczas jednego z warsztatów Scrum, wraz z grupą doświadczonych Zespołów Deweloperskich przyjrzeliśmy się najczęstszym źródłom technical debt. Nasze obserwacje były nie tyle zaskakujące, co… oczywiste.

Przede wszystkim musimy sobie powiedzieć szczerze, że technical debt powstaje bardzo szybko. Może brzmi to śmiesznie, ale to jest trochę tak jak ze znanym nam już Broken Window Theory czy efektem kuli śnieżnej:

“Efekt kuli śnieżnej – proces, który rozpoczyna się na małą skalę i stopniowo rozrasta, stając się większym. Istotnym aspektem efektu jest to, że im bardziej zaawansowany jest dany proces, tym trudniej go zatrzymać” – Wikipedia

Problem z zatrzymaniem przyrostu długu technologicznego polega na tym, że istnieje wiele jego źródeł, takich jak kod, przyjęte rozwiązanie, testy, środowiska testowe i wdrożeniowe czy wymagania niefunkcjonalne.

W ramach każdej z kategorii udało nam się zidentyfikować szereg czynników, mających wpływ na rosnący technical debt. W przypadku kategorii Kod były to jakość, skomplikowanie i reużywanie (a raczej jego brak). Jeśli chodzi o kategorię Rozwiązanie możemy napotkać na problemy z architekturą czy zbyt dużą liczbą zależności. W ramach kategorii Testy zwykle jest to brak lub niewystarczająca ilość testów manualnych i automatycznych.

Przyglądając się Środowiskom, uczestnicy szkolenia wskazali na brak zintegrowanych środowisk umożliwiających testy end-to-end bądź znaczące różnice pomiędzy środowiskami testowymi i wdrożeniowymi. W końcu do kategorii Wymagania niefunkcjonalne zaklasyfikowaliśmy wszystkie życzenia nie mające bezpośredniego wpływu na biznesową część funkcjonalności.

Nie są to wszystkie triggery technical debt (ach, ten slang), ale z na pewno udało się nam znaleźć te występujące najczęściej. A jeśli udało się nam je znaleźć, to zgodnie z podejściem Inspect & Adapt możemy przygotować i wdrożyć pewne rozwiązania.

 

Jak walczyć z technical debt?

Uświadomienie sobie, że mamy problem z jakąś rzeczą to pierwszy krok do rozwiązania problemu. Skoro wiemy, że dług technologiczny powstaje w wyniku wskazanych wyżej czynników, przyjrzyjmy się możliwościom ich rozwiązania.

Zaskakująco, na wiele z powyższych problemów odpowiada podejście Continuous Integration, czyli inaczej mówiąc technika ciągłego wdrażania. Zachęcam tych, którym termin ten jest obcy, do zapoznania się z jego opisem na blogu #białko.

Implementując zestaw działań związanych z ciągłym wdrażaniem, szybko znajdziemy rozwiązania na zidentyfikowane przez nas problemy dotyczące kodu, testów czy środowiska. Nie znajdziemy tam natomiast pomocy w sprawie części analityczno-architektonicznej i wymagań niefunkcjonalnych.

Nasze doświadczenie podpowiada jednak rozwiązania w ramach tzw. dobrych praktyk. Wymagania niefunkcjonalne wydzielmy do osobnych User Stories i realizujmy je dokładnie tak samo, jak inne wymagania funkcjonalne po uzgodnieniu ich priorytetów z Interesariuszami. Alternatywnie, jeżeli nasz produkt musi spełniać określone wymagania (np. systemy embedded), zadbajmy o ich zapewnienie na poziomie Definition of Done.

Jeśli chodzi o jakość architektury rozwiązania i liczne powiązania pomiędzy poszczególnymi funkcjonalnościami, zdejmijmy odpowiedzialność za jej tworzenie z barków jednego zespołu lub, jak często ma to miejsce, jednego człowieka. Oddajmy tę część w ręce ludzi odpowiedzialnych za późniejsze wykonanie prac, czyli w ręce zespołu deweloperskiego. To zespół ma skin in the game i na pewno zaprojektuje rozwiązanie w taki sposób, aby możliwa była jego sprawna realizacja.

 

Złe przyczyny “dobrego” technical debt

Samo występowanie technical debt nie wydaje się niczym złym, o ile jego źródłem pochodzenia jest optymalizacja rozwiązań pod kątem wytworzenia MVP. Niestety, dług pochodzący z pozostałych wymienionych powyżej przyczyn trudno obronić.

Przytoczę fragment konkluzji poprzedniego artykułu:

“Najważniejsze jest jednak to, co dziś zrobimy z dostępnymi środkami. Ich odpowiednie zainwestowanie dziś spowoduje korzyści, które mogą przewyższać koszta w przyszłości.” – #białko

Powyższa konkluzja to jedna strona medalu. Drugą stroną są obciążające nas w coraz większym stopniu źródła długu. Jeśli chcemy mieć możliwość gospodarowania dostępnymi środkami dziś bez konieczności ratowania się za chwilę przyjrzyjmy się przyczynom, dla których pojawia się technical debt. Ich wyeliminowanie spowoduje, że będziemy mogli skupić się na optymalnym wykorzystaniu dostępnych dziś środków, bez zaciągania długu.

Łukasz Bręk

14 lat doświadczenia w IT, 7 lat doświadczenia w Scrum, PSM, PSPO, Scrum Master zespołów zwinnych, Product Owner, analityk biznesowy, trener Scrum

Click Here to Leave a Comment Below

Leave a Reply: