O długach i kredytach słyszymy na każdym kroku. W dobie wszechobecnego konsumpcjonizmu karty kredytowe, leasingi i kredyty hipoteczne to codzienność. O długu technicznym czy technologicznym też słyszał chyba każdy, kto ma styczność z projektami informatycznymi. Niemniej jednak, przemyślane i niebanalne podejście do tematu widuje się zaskakująco rzadko.  Jak zdefiniować dług techniczny, co różni go od zwykłego niedbalstwa oraz jak możemy go mierzyć – to wszytko wyjaśnię w poniższym wpisie.

Czym jest dług?

Dług jest pewnego rodzaju zobowiązaniem, czy może raczej obowiązkiem spłaty tego zobowiązania na rzecz wierzyciela. Zwyczajowo od długu nalicza się odsetki, które podwyższają podstawowe zobowiązanie. Im szybciej taki dług spłacamy, tym mniejsze odsetki oddajemy. Podobnie sprawa wygląda z długiem technicznym. W tym wypadku odsetki przybierają formę dłuższego czasu wymaganego do wdrożenia zmian. Przyczyny występowania długu technicznego są różne. Czasem wprowadza się go świadomie poprzez wdrażanie rozwiązań tymczasowych czy też z uwagi na istotne okoliczności zewnętrzne. Z reguły jednak jest on konsekwencją presji biznesowej, błędnych decyzji projektowych, przekładania w nieskończoność refactoringu czy aktualizacji zależności.

Czym dług techniczny nie jest?

Jeżeli dług ma mieć jakikolwiek sens, musi, tak jak kredyt, nieść ze sobą jakąś korzyść. Tak samo zaciągnięcie długu technicznego musi gwarantować solidny zysk. Nie jest to więc efekt złych praktyk, wynikających zazwyczaj z lenistwa bądź braku umiejętności. Jeżeli nie piszemy testów i świadomie rezygnujemy z techniki Test Driven Development, to stwierdzenie, że robimy to, „żeby było szybciej”, jest po prostu zakłamywaniem rzeczywistości. Nawet jeżeli samo napisanie kodu będzie trwało krócej (z czym zresztą praktycy TDD się nie zgodzą), to już jego wdrożenie na produkcję czy też pierwsza modyfikacja cały ten „bonus” pochłonie. Podobnie jest z ignorowaniem podstawowej struktury kodu. Tworzenie ogromnych metod (mających po kilka tysięcy linii), dlatego, że nie ma czasu na refactoring? A tak szczerze – ile zajmuje wydzielenie fragmentu do osobnej metody? 5 sekund? Nie oszukujmy się zatem, że nie robimy tego z powodu braku czasu.

Metryki długu technicznego

Jak mierzycie w projekcie dług techniczny? „MD to fix” wyświetlane przez SonarQube? To wyjątkowo popularna metoda, ale według mnie wyjątkowo bezwartościowa. Nie jest to liczba, która realnie jest w stanie wpłynąć na czas dostarczania zmian, jakość procesu wytwórczego czy też bezpieczeństwo aplikacji. Jak inaczej możemy ugryźć temat pomiaru długu? Przede wszystkim należy zastanowić się, w czym nam on w ogóle przeszkadza. Według mnie podstawowy problem dotyczy właśnie czasu wykonania zmian, zarówno ze względu na pracochłonność ich implementacji, jak i czas potrzebny na kompilacje i wdrożenie. Jak można przełożyć to na liczby?

„Czas potrzebny na podbicie wersji zależności po publikacji CVE. Przyjmijmy wartość 15 minut. Co gwarantuje ta metryka? Przede wszystkim szybką reakcję na opublikowanie podatności bezpieczeństwa, w wykorzystywanych przez nas bibliotekach czy narzędziach. Powiedzmy sobie szczerze, że w tak krótkim czasie możemy zaktualizować się tylko o wersję patch (zgodnie z wersjonowaniem semantycznym). Zatem, aby utrzymać tak rygorystyczne kryteria, musimy regularnie dbać o aktualizację wersji minor i major, aby cały czas wykorzystywać linię zapewniającą stałe wsparcie dostawcy/autorów. Samo podbicie zależności to jednak dopiero połowa sukcesu. Należy jeszcze wdrożyć zaktualizowaną paczkę na produkcję. I tu pojawia się druga metryka.

„Czas od commitu (wykonania) zmiany do wdrożenia jej na wszystkie instancje produkcyjne”. Znów 15 minut. Tym razem dbamy o to, aby kompilacja aplikacji była możliwie szybka. Następnie wykonujemy wdrożenie na środowisko staging, tam testujemy podstawowe procesy biznesowe. Po prawidłowym zakończeniu testów rozpoczynamy wdrożenie produkcyjne. Oczywiście bez pełnej automatyzacji uzyskanie tak krótkiego czasu byłoby niemożliwe. Zarówno testy, jak i wdrożenia czy restarty, muszą być wykonywane bez ingerencji człowieka. To zapewnia także powtarzalność i dobrą estymację czasu wykonania.

Także strukturę kodu możemy pośrednio kontrolować za pomocą metryk. „Procent klas oznaczonych jako publiczne”. W skrócie – im więcej klas jest wystawionych publicznie, tym łatwiej doprowadzić system do postaci spaghetti. Klasa upubliczniona, czyli dostępna z dowolnego miejsca w systemie. Często właśnie z lenistwa upubliczniamy więcej niż trzeba. W Javie jest to głównie związane z domyślnymi ustawieniami IDE, które każdą klasę oznaczają jako publiczną. Sama zmiana tego jednego szablonu daje ogromną poprawę jakości tworzonego kodu. Jednak nawet wtedy trzeba pilnować się, aby otwierać jedynie te klasy, które faktycznie są interfejsem danego pakietu/modułu, a nie te, których kawałek akurat przyda się w innym miejscu.

A jak w Waszych projektach wygląda mierzenie się z długiem technicznym? Zachęcam do dyskusji w komentarzach.

5
Dodaj komentarz

avatar
2 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
Jakub Kubryński0xmarcinMichal KulińskiTomek Kopczyński Recent comment authors
  Subscribe  
najnowszy najstarszy oceniany
Powiadom o
Tomek Kopczyński
Gość
Tomek Kopczyński

Mam jeszcze jeden pomysł na metrykę. Wiem, że nie zawsze się sprawdza, ale dla mnie często jest sygnałem, że coś w kodzie źle się dzieje. Mianowicie, chodzi o duże rozjazdy pomiędzy szacowaniem tasków przed implementacją, a faktycznym czasem wykonania. Wiem, że to nigdy się nie pokrywa 🙂 ale jeśli z czasem zespół coraz gorzej szacuje i dodatkowo okazuje się, że nawet banalne z pozoru rzeczy (w sensie komplikacji samego problemu) zajmują mnóstwo czasu poświęconego na kodowanie, to może to wskazywać na narastanie długu.

Nie jest to może zbyt ścisła metryka, ale może być jakimś wskaźnikiem „na czuja”.

0xmarcin
Gość

A my w moim zespole zrezygnowaliśmy zupełnie z szacowania. Jak można wyszacować kreatywną pracę (w tej chwili skupiamy się prawie wyłącznie na nowych funkcjonalnościach które na dodatek są dosyć mgliście zdefiniowane i nabierają kształtu dopiero podczas iteracyjnego dostarczania i rozmów z klientami). Oczywiście to działa pod warunkiem że przymiemy bardziej Kanbanowy model wciągania zadań (jak są wolne przebiegi to dodajemy taski, ale jest sztywny limit na Work in progress – więc dodajemy tylko jak obecne taski są skończone, jak jesteśmy zblokowani to staramy się rozwiązać problem a nie dokładać inną pracę)

Michal Kuliński
Gość

Dzięki za artykuł.
Świetny artykuł i pomysł z metryką klas publicznych.
U mnie 80 procent roboty robią dwie metryki:
– jak i gdzie kod duplikuje się
– aktualna liczba nieprzechodzących testów

P. S. Polecam dwa świetne filmy na Clean Coders o długu technologicznym autorstwa Doca Nortona