Funkcja działa. Testy przechodzą. Kod trafi na produkcję. Ale wszyscy w zespole wiedzą, że napisano to na skróty - bo był deadline, bo nie było czasu na refaktoryzację, bo „poprawimy to później".
To „później" rzadko nadchodzi samo z siebie. I właśnie tak narasta dług techniczny.
Dług techniczny to jeden z największych ukrytych kosztów w projektach IT. Nie widać go w wykresach sprintów ani w raportach dla klientów. Widać go za to w spowolnieniu pracy, rosnącej liczbie bugów i coraz dłuższym czasie wprowadzania nowych funkcji.
Czym jest dług techniczny
Pojęcie długu technicznego (ang. technical debt) wprowadził Ward Cunningham w latach 90. Tak jak dług pieniężny nalicza „odsetki" - każdy skrót i uproszczenie w kodzie sprawia, że przyszłe zmiany kosztują więcej czasu i wysiłku.
Dług techniczny to każda decyzja projektowa lub implementacyjna, która przyspiesza pracę w krótkim terminie i spowalnia pracę w długim terminie. Może to być: kod napisany bez testów, zduplikowana logika, przestarzałe biblioteki, architektura, która nie skaluje się z rozwojem projektu, brak dokumentacji, sztuczki i obejścia zamiast właściwych rozwiązań.
Ważne: dług techniczny nie zawsze jest błędem. Czasem świadome zaciągnięcie długu - żeby zdążyć z ważnym terminem - jest rozsądną decyzją biznesową. Problem pojawia się wtedy, gdy dług nie jest spłacany.
Rodzaje długu technicznego
Celowy vs. przypadkowy
Dług celowy to świadoma decyzja o zaciągnięciu skrótu. Zespół wie, że pisze nieoptymalne rozwiązanie, ale robi to świadomie - np. żeby zdążyć z premierą produktu.
Dług przypadkowy powstaje bez świadomości zespołu - z powodu nieznajomości dobrych praktyk, błędnych decyzji architektonicznych lub niedoświadczenia.
Ostrożny vs. lekkomyślny
Dług ostrożny to dług zaciągnięty celowo i świadomie, z pełnym rozumieniem konsekwencji. Zespół mówi: „Wiemy, że to rozwiązanie jest nieoptymalne, ale wrócimy do tego w kolejnym sprincie."
Dług lekkomyślny to dług zaciągnięty bez rozumienia konsekwencji lub bez planu spłaty. Najgroźniejszy jest dług lekkomyślny i przypadkowy - to połączenie prowadzi do kodu, którego nikt nie rozumie i którego nikt nie chce dotykać.
Jak rozpoznać dług techniczny
Sygnały w kodzie: komentarze w stylu // TODO: naprawić to kiedyś, funkcje liczące kilkaset linii, skopiowany kod w wielu miejscach, brak testów dla krytycznych funkcji, przestarzałe zależności.
Sygnały w pracy zespołu: coraz dłuższy czas wdrażania nowych funkcji, rosnąca liczba bugów po każdym wydaniu, strach przed modyfikacją istniejącego kodu, każda zmiana „ciągnie" za sobą nieprzewidywalne efekty uboczne.
Jak mierzyć dług techniczny
Narzędzia takie jak SonarQube, CodeClimate czy ESLint wykrywają code smells, duplikaty, naruszenia standardów i szacują czas potrzebny do ich naprawy. SonarQube podaje nawet konkretny szacunek w godzinach.
Możesz też estymować dług jak funkcjonalności: każdy element długu jest szacowany przez zespół w punktach lub godzinach. Suma tych szacunków to całkowity dług.
Skutki ignorowania długu technicznego
Spowolnienie developmentu. Każda nowa funkcja jest coraz trudniejsza do wdrożenia. Prosta zmiana, która powinna zająć godzinę, zajmuje dzień.
Więcej bugów. Nieczytelny kod jest źródłem błędów. Developerzy boją się zmieniać kod, więc stosują obejścia, które generują kolejne problemy.
Wypalenie zespołu. Praca w projekcie z dużym długiem technicznym jest frustrująca. Morale spada, rotacja rośnie.
Wyższe koszty. W pewnym momencie koszt utrzymania projektu przewyższa koszt jego przepisania od zera.
Wolniejszy onboarding. Nowa osoba w zespole spędza tygodnie próbując zrozumieć kod bez dokumentacji i z dziesiątkami nieintuicyjnych skrótów.
Jak zarządzać długiem technicznym w praktyce
Priorytetyzacja
Dług techniczny w większości projektów jest tak duży, że nie da się go spłacić naraz. Pytania, które pomagają ustalić priorytety: Który dług najbardziej spowalnia bieżące prace? Który dług generuje najwięcej bugów? Który dług utrudnia onboarding nowych osób?
Zasada harcerska (Boy Scout Rule)
Przy każdej modyfikacji kodu zostaw go w lepszym stanie niż go znalazłeś. Nie musisz przepisywać całego modułu - wystarczy poprawić nazwy zmiennych, dodać test dla funkcji, którą właśnie dotknąłeś, usunąć nieużywany kod. Ta zasada pozwala spłacać dług stopniowo, bez blokowania nowych funkcji.
Dedykowane sprinty
Niektóre zespoły rezerwują co kilka sprintów jeden sprint wyłącznie na spłatę długu technicznego. Aby uzyskać wsparcie interesariuszy, warto pokazać konkretne dane: „Ten sprint pozwoli nam przyspieszyć development o 20% w ciągu kolejnych trzech miesięcy."
Reguła 20%
Popularne podejście: 20% każdego sprintu przeznaczamy na spłatę długu technicznego. Dzięki temu dług nie narasta, a nowe funkcje nadal są dostarczane. Dla projektów z dużym długiem może to być 30-40% przez kilka sprintów.
Dokumentuj decyzje o zaciągnięciu długu
Gdy świadomie zaciągasz dług - zapisz to. W komentarzu w kodzie, w zadaniu w systemie PM, w dokumentacji architektury. Powinno być zapisane: dlaczego zdecydowano się na to rozwiązanie, jakie są jego ograniczenia, kiedy planuje się je poprawić.
Jak śledzić dług techniczny w Taskello
Dług techniczny warto traktować jak każde inne zadanie. W Taskello możesz stworzyć dedykowany projekt lub etykietę „Dług techniczny" i zbierać tam wszystkie elementy wymagające poprawy. Dzięki temu product owner widzi, ile długu narosło i może uwzględnić jego spłatę w planowaniu sprintów, a developerzy mogą dodawać elementy długu do backlogu bezpośrednio podczas pracy.
Dług techniczny a code review
Jednym z najlepszych sposobów zapobiegania nowemu długowi technicznemu jest solidny proces code review. Przeczytaj nasz artykuł o tym, jak robić code review dobrze i nie tracić czasu.
Jak rozmawiać o długu technicznym z biznesem
Mów językiem biznesu, nie technicznym. Zamiast „mamy code smells w warstwie usług", powiedz „każda nowa funkcja w tym obszarze zajmuje nam dwa razy więcej czasu niż powinna". Pokazuj liczby: velocity, czas naprawy bugów, czas wdrożenia funkcji. Proponuj konkretne rozwiązania z mierzalnymi efektami.
Podsumowanie
Dług techniczny jest nieunikniony - szczególnie w projektach, które szybko się rozwijają. Kluczem nie jest jego unikanie za wszelką cenę, ale świadome nim zarządzanie.
- Rozróżniaj dług celowy (świadomy) od przypadkowego (niezamierzonego).
- Śledź dług techniczny jak każde inne zadanie - w backlogu.
- Priorytetyzuj dług, który najbardziej spowalnia bieżące prace.
- Stosuj zasadę harcerską: zostawiaj kod w lepszym stanie niż go znalazłeś.
- Przeznaczaj regularnie część każdego sprintu na spłatę długu.
Dług techniczny, którym się zarządza, jest narzędziem. Dług, który się ignoruje, staje się pułapką.