Strona główna / blog / Co to jest dług technologiczny i jak sobie z nim poradzić
Co to jest dług technologiczny i jak sobie z nim poradzić

Poruszone tematy:

Problemy z działaniem oprogramowania, czy jego niedoskonałości nie są niczym niezwykłym, gdyż w tysiące linijek kodu zawsze może wkraść się jakiś niechciany bug. Niedostatki i błędy w kodzie często mają jednak szerszy zakres i wynikają z celowych lub niezamierzonych praktyk programistów. To właśnie dług technologiczny, o którym poniżej.

Co to jest dług technologiczny i kiedy się pojawia?

Dług technologiczny to domniemany koszt dodatkowych przeróbek spowodowany wyborem łatwiejszych, mniej kosztownych rozwiązań, wynikających z braku kompetencji lub szybszych rozwiązań podczas tworzenia kodu zamiast skutecznych i solidnych.

Pojawia się najczęściej w momencie, gdy zespół jest zbyt mały do powierzonych zadań i trzeba podejmować decyzje o uproszczeniach oraz pomijaniu pewnych procesów jakościowych i wydajnościowych. Najczęstszą jego przyczyną jest presja czasowa narzucona od strony klienta, a jednocześnie cięcia budżetu na realizację projektu (więcej o wycenach projektów).

Drugim czynnikiem sprzyjającym powstaniu długu technologicznego jest powierzenie projektu osobom, które nie mają wystarczających kompetencji do realizacji powierzonych zadań - w szczególności tych, które są bardziej skomplikowane i wymagają większego zastanowienia się, bo będą rzutować nad dalszym rozwojem projektu w przyszłości. Ważne jest także, aby nad projektem czuwała doświadczona osoba pod kątem technicznym, która będzie pełniła funkcję Tech Leada. Rozplanuje on dokładną architekturę projektu, flow prac, będzie mentorem dla zespołu i skoordynuje wszystkie prace.

Trzecim czynnikiem długu technologicznego to brak bieżącego refaktorowania kodu. Jest to bardzo ważny proces, który zazwyczaj jest pomijany ze względu na dodatkowe koszty i poświęcony czas. W przypadku braku bieżącego dopracowywania kodu, wraz ze zmianą założeń różnych funkcji i tworzenia "obejść" zamiast refaktoryzowania, kod staje się coraz bardziej kruchy na kolejne zmiany i mniej wydajny.

Mimo że firma oszczędza dzięki wdrażaniu szybciej i taniej stworzonego rozwiązania musi ponosić tego koszty później. Odsetki od zaciągniętego długu z czasem rosną i staje się on trudniejszy do spłacenia, ponieważ poprawienie oprogramowania jest coraz droższe i rodzi coraz więcej problemów i błędów.

Dług technologiczny może być także zaciągany nieintencjonalnie, kiedy zespół otrzymuje błędne założenia, co do działania pewnej funkcjonalności, która z czasem okazuje się źle zaprojektowana.

Dług roku 2000

Najsłynniejszym przykładem długu technologicznego jest tzw. problem roku 2000. Polegał na zapisie daty w formacie składającym się z jej dwóch ostatnich cyfr. Pojawiła się w związku z tym obawa, że komputery zinterpretują rok 2000 jako 1900, co mogło doprowadzić do poważnych zakłóceń w działaniu wielu systemów.

Cały problem wynikał z faktu, że wielu twórców oprogramowania w latach 60. i 70. postanowiło oszczędzać kosztowną wówczas pamięć komputerów, decydując się właśnie na dwucyfrowy zapis dat. Programy te pozostały w użyciu znacznie dłużej, niż się tego spodziewano. U końca millenium rozpoczęto zatem akcję rozwiązywania tego problemu, która kosztowała około 200-300 miliardów dolarów.

2000

Rodzaje długu technologicznego

  • celowy

    Pojawia się zazwyczaj, gdy priorytetem są terminy. Organizacja najczęściej uwzględnia w swoim budżecie jego spłacenie, ale rzadko kiedy dochodzi to później do skutku i jest on konsekwentnie zwiększany z biegiem czasu.

    Często ma to miejsce przy tworzeniu MVP (Minimum Viable Product), czyli najprostszej opłacalnej wersji produktu. MVP pozwala wcześniej wypuścić oprogramowanie i sprawdzić, czy użytkownicy będą nim zainteresowani, czy się sprawdzi na rynku (weryfikacja biznesowa pomysłu). Jeżeli produkt się nie sprawdzi, można dzięki temu uratować sporą część kapitału, który zostałby wydany w celu napisania kompletnego i dopracowanego oprogramowania. Natomiast gdy produkt okaże się trafiony, kod będzie można poprawić lub zupełnie przepisać - jeśli pominiemy ten proces, dług technologiczny będzie rósł wraz z każdą kolejną iteracją rozwijania oprogramowania.

  • niezamierzony

    Pojawia się często, gdy zespół programistyczny nie ma wystarczającego doświadczenia i odpowiednich umiejętności, by rozpoznać moment powstania długu. Mogą to być błędy w którejś z podstawowych warstw oprogramowania - w szczególności źle zaprojektowanej architektury, co rzutuje na całokształt rozwijanego produktu i tworzone kolejno następne warstwy i elementy.

    Zespół może też nie być świadomy "dlaczego to nie działa" z uwagi na jego nieoczywistą formę - mogą nie potrafić wykryć długu lub wymaga to mozolnych i długich poszukiwań. Taki dług wymaga następnie czasochłonnych poprawek, a nawet przepisania dużej części kodu.

    Jednak zaciągnięcie długu technologicznego zdarza się także doświadczonym programistom. Jeżeli eksplorują nowy dla siebie obszar, mogą po jakimś czasie zauważyć, że daną funkcjonalność można było zakodować w inny, znacznie lepszy sposób. To naturalna konsekwencja uczenia się zespołu nawet o wysokich kompetencjach. Dlatego tak bardzo ważne jest, aby projekt był prowadzony zawsze pod okiem doświadczonego Tech Leada, a z całym zespołem były przeprowadzane stałe konsultacje na temat rozwijania i dopracowywania kodu.

  • dług dokumentacji

    To dość częsty rodzaj długu, który pojawia się, gdy programiści działają w pośpiechu i niedokładnie dokumentują kod. Staje się on dla innych programistów niezrozumiały i wymaga dłuższej analizy przez osoby, które muszą zrozumieć jego działanie. Znacząco utrudnia to wdrożenie się nowych osób do projektu, jak i dalszy rozwój oprogramowania przez osoby, które kod w praktyce dobrze znają. Wystarczy chwila przerwy w projekcie i po czasie, bez dokładnej dokumentacji czy skomentowanego kodu, nawet osoba, który dany fragment kodu napisała, może mieć problem z przypomnieniem sobie jego dokładnego działania i tego, co dokładnie miała na myśli. Powoduje to często upraszczanie dalszego rozwoju tego fragmentu kodu i stosowanie obejść, które przyczyniają się do coraz gorszej jakości pisanego kodu (pomimo że początkowo był bardzo dobrej jakości).

  • dług infrastruktury

    Pojawia się, gdy aplikacje są ściśle zależne od określonych składników infrastruktury serwerowej, np. baz danych, narzędzi cache, czy systemów plików. Przy braku udokumentowania takich zależności, po ewentualnej migracji oprogramowania do nowej infrastruktury może ono przestać działać. Innym istotnym czynnikiem jest dbałość o stałe aktualizowanie oprogramowania i audyt infrastruktury. Jeśli się to zaniedba, narażamy się na zaprzestanie lub spowolnienie działania projektu w przyszłości, lub co gorsza, pojawienie się luk bezpieczeństwa, które mogą się przyczynić do włamania i innych ataków hakerskich.

  • środowiskowy

    Dotyczy poprawnie napisanych i działających programów, które funkcjonują poprawnie od dłuższego czasu, niemniej są one niewłaściwie zarządzane po wdrożeniu. Z czasem środowisko, w którym działają, ulega zmianie i mogą pojawić się między nim a aplikacją niezgodności. Dotyczy to np. sytuacji, gdy zaistnieją zmiany w systemie operacyjnym (aktualizacja) lub API usług zewnętrznych zostanie zmodyfikowane/przestanie być wspierane. Jeśli oprogramowania nie dostosowuje się do zmian środowiska i nie będzie na bieżąco aktualizowane, aplikacja przestanie prawidłowo działać (poszczególne jej funkcje), a dług technologiczny z czasem będzie narastał i doprowadzi do całkowitego zaprzestania działania aplikacji.

don't repeat yourself

Oznaki długu technologicznego

Identyfikacja długu technologicznego jest łatwa, gdy został zaciągnięty celowo. Tworząc np. MVP, programiści dokumentują dług podczas kodowania, by wiedzieć, które elementy będzie trzeba w przyszłości poprawić. Rozwiązanie traktowane jest jako tymczasowe a spłata długu zaplanowana.

Inne rodzaje długu zidentyfikować jest już znacznie trudniej. Sposobem może być analiza logów błędów oraz stała analiza wydajności działania. Kluczem jest także gromadzenie opinii użytkowników (feedback), którzy mogą wskazywać powtarzające się problemy, jak np. narastające pogarszanie się wydajności aplikacji lub nieprawidłowe działanie niektórych funkcji.

Analizuje się także kod. O długu technologicznym może świadczyć kod nieczytelny i o złożonej logice, który trudno jest modyfikować i rozbudowywać. Często architektura aplikacji jest nieprzemyślana, co rodzi trudności w dalszym rozwijaniu oprogramowania. Staje się ono podatne na coraz większą ilość błędów i spadek wydajności.

Oznaką długu bywa także duża ilość martwego, niewykorzystanego kodu oraz kodu zduplikowanego, łamiącego zasadę DRY (Don't Repeat Yourself). Zdarza się także, że niektóre fragmenty kodu są po prostu zakomentowane, bo najprościej było wyłączyć działanie danej funkcji, jednakże powoduje to ogólny bałagan. Zwrócić uwagę należy także na zwiększenie nakładu pracy związanej z testami manualnymi, które po czasie mogą być coraz częściej pomijane lub skracane (co bezpośrednio naraża na wydanie niestabilnej aplikacji).

#agile

Metody zarządzania długiem technologicznym i zapobiegania jego powstawaniu

Kiedy dług technologiczny zaistnieje lub został celowo zaciągnięty, kluczowe jest, żeby zdawać sobie z niego sprawę i odpowiednio nim zarządzać. Jeżeli nie planujemy zaciągać długu technologicznego, warto jest stosować metody, które pozwalają go uniknąć.

  • Wprowadzenie standardów i recenzji kodu

    Dobrą praktyką jest stworzenie zbioru zasad programowania i listy dobrych praktyk. Jeśli programiści będą ich ściśle przestrzegać można uniknąć powstania długu technologicznego lub powstały dług nie będzie narastał, bo będzie na bieżąco wyprowadzany (stała refaktoryzacja kodu).

    Jedną z metod ograniczenia występowania błędów w kodzie jest technika programowania w parach (pair programming). Zgodnie z nią jeden z programistów jest odpowiedzialny za wpisywanie kodu, drugi za monitorowanie kodu oraz wyznaczanie strategicznych celów budowania aplikacji. Programiści piszą wtedy kod wspólnie, co chwilę zamieniając się rolami. Pozwala to także na wczesne wyłapywanie błędów lub stosowanych uproszczeń w kodzie i zapobieganie im.

    Oprócz ciągłego analizowania kodu w parach bardzo ważnym aspektem jest końcowy przegląd kodu przez innego programistę lub Tech Leada w zespole. Gdy dany programista kończy pracę nad daną funkcjonalnością, wystawia kod do wglądu dla innego specjalisty, w celu zatwierdzenia zmian lub ich odrzucenia (pod kątem dopracowania). Pozwala to na wnikliwe pilnowanie jakości kodu.

  • Przyjęcie metodologii agile

    Zwinne metodologie programowania (takie jak Scrum) pozwalają rozwiązywać problem długu technologicznego na bieżąco, dzięki regularnym dyskusjom, analizom i inspekcjom kodu przez osoby w zespole, podczas cyklicznych spotkań (zazwyczaj codziennych i podsumowujących raz w tygodniu). Spotkania służą temu, aby na bieżąco omawiać wszelkie potencjalne problemy w projekcie i zaplanować odpowiednio optymalne strategie jego dalszego rozwoju. Wszystkie czynności procesu są także zawarte w backlogu (dzienniku projektu), co ułatwia śledzenie powstawania długu.

  • Refaktoryzacja kodu (przekształcanie go do bardziej czytelnej postaci)

    Refaktoryzacja to nieustanny proces poprawiania kodu (zarówno od strony jakościowej, jak i koncepcyjnej). Dzięki regularnemu przeprowadzaniu refaktoryzacji kod stanie się łatwiejszy w utrzymaniu i bardziej zrozumiały dla pozostałych programistów. Pozwoli to ograniczyć dług technologiczny do minimum i zachować aktualność oprogramowania względem zmieniających się standardów. Trzeba pilnować także, aby nie wprowadzać do systemu nadmiernej złożoności, która zbytnio skomplikuje kod i utrudni później jego zrozumienie (refaktoryzacja musi przebiegać w umiarkowanym stopniu, lecz nieustannie).

  • Wdrażanie testów automatycznych

    Testy automatyczne znacznie ułatwiają i przyśpieszają wykrywanie bugów. Jednocześnie w dużej części eliminują testy manualne, które są czasochłonne, ich przebieg jest trudno dokładnie powtórzyć oraz wiąże się z nimi ryzyko popełnienia błędu lub niedopatrzenia przez testera.

    Za pomocą testów automatycznych można uruchamiać wiele cykli debugowania, które przeprowadzane są na podstawie wcześniej stworzonych scenariuszy. Jednocześnie zazwyczaj wymagają one uzupełnienia w postaci testów ręcznych, których zaletą jest uzyskiwanie bezpośrednich informacji zwrotnych od programistów/testerów.

  • Korzystanie z narzędzi do zarządzania projektami

    Narzędzia do zarządzania projektami (jak np. Jira, Clickup, ActiveCollab, Trello) pozwalają na lepsze zaplanowanie projektu i komunikację w zespole. Porządkują i synchronizują pracę oraz umożliwiają wyznaczanie zadań poszczególnym członkom zespołu. Każdy task zawiera szczegółowy opis merytoryczny, jak i techniczny funkcji, która będzie zaimplementowana. Pozwala także na dyskusję w ramach tasków, dzięki czemu można pewne kwestie poruszyć już na poziomie danego zadania. Korzystanie z nich to skuteczny sposób na zarządzanie większymi projektami i zespołami, także dzięki dostępowi do współdzielonych dokumentów czy kalendarzy.

Dług technologiczny - problem do rozwiązania

Technologiczne "zadłużanie się" podczas tworzenia oprogramowania to częste zjawisko. Dopóki jest to celowe zaciąganie długu, stosunkowo łatwo go potem spłacić, jeżeli taka będzie decyzja zespołu. Aby jednak było to proste, niezbędne jest dokładne dokumentowanie kodu oraz wcześniejsze zaplanowanie przebiegu przyszłych poprawek. Jeśli w odpowiednim czasie kod zostanie dopracowany, ryzyko długu technicznego maleje, tak więc liczy się tutaj konsekwencja i stały nadzór nad jakością wytwarzanego kodu.

Gorzej, gdy programiści zadłużają się nieświadomie w wyniku pośpiechu, wyboru prowizorycznych rozwiązań czy braku odpowiedniego doświadczenia i wiedzy. Wtedy pozostaje jedynie mozolne wyszukiwanie błędów i poprawianie kodu, pod warunkiem, że ktoś zwróci uwagę na taką potrzebę. Często jednak bywa, że nieświadomość trwa bardzo długo i finalnie projekt osiąga ścianę, którą ciężko ominąć.

Aby tego uniknąć, należy od początku trzymać się dobrych praktyk tworzenia oprogramowania - przeprowadzać regularne testy i zachowywać staranność przy pisaniu kodu źródłowego. Chociaż bywa to czasochłonne, koniec końców okazuje się zdecydowanie tańsze niż późniejsze poprawki oraz koszty niezadowolenia użytkowników wadliwego oprogramowania, jak i frustrację klienta, przez prace nad projektem, które stają się coraz trudniejsze i droższe.

dług technologicznyco to jest dług technologicznykiedy pojawia się dług technologicznyrodzaje długu technologicznegooznaki długu technologicznego
Ta strona używa plików cookiesPolityka PrywatnościJak wyłączyć cookiesCyberbezpieczeństwo
OK