Porady

Legacy code: dlaczego boisz się zmienić kod, który działa

Każda firma technologiczna ma kod, którego nikt nie chce dotykać. Kod, który działa, generuje przychody i trzyma biznes przy życiu. Problem w tym, że każda próba jego zmiany kończy się nieoczekiwanymi błędami, nocnymi wdrożeniami i frustracją zespołu. Ten kod ma nazwę: legacy code. I wbrew temu, co sugeruje słowo „legacy”, problem nie polega na tym, że kod jest stary. Problem polega na tym, że kod ten stał się „dziedzictwem” w wyniku lat narastającego długu technicznego. To właśnie niespłacone odsetki od dawnych kompromisów jakościowych sprawiły, że system stał się nieprzewidywalny i paraliżuje zespół.” Dobra wiadomość? Strach przed legacy code można pokonać. Wymaga to zrozumienia, czym naprawdę jest legacy code, świadomego podejścia do długu technicznego i stopniowej modernizacji zamiast ryzykownego przepisywania od zera.

Czym jest legacy code?

Nicolas Carlo na blogu Understanding Legacy Code definiuje legacy code jako wartościowy kod, którego boisz się zmienić. Nie chodzi o wiek kodu. Chodzi o dwa elementy: wartość i strach.

Wartość oznacza, że kod działa w produkcji, generuje przychody, firma na nim stoi. Gdyby nie działał, firma by upadła i nie miałbyś problemu z legacy code. Strach oznacza, że nie wiesz, jak zmienić kod bez zepsucia istniejącego zachowania.

Skąd ten strach? Carlo wskazuje na nieznajomość kodu, lata pracy wielu osób pod presją czasu i skróty podejmowane, by zdążyć z deadlinami. Każdy taki kompromis to dług techniczny, który narasta i utrudnia zmiany. Legacy code to perspektywa, nie cecha samego kodu. Ale ta perspektywa jest bezpośrednim skutkiem skumulowanego długu.

Jak legacy code powstaje: rola długu technicznego

Dług techniczny to świadome lub nieświadome kompromisy, które przyspieszają dostarczanie wartości kosztem przyszłej elastyczności kodu. Sam w sobie nie jest zły. Problem zaczyna się, gdy wymyka się spod kontroli i zamienia kod w legacy.

Analogia do długu finansowego jest trafna. Czasem warto pożyczyć, by szybciej rosnąć. MVP wymaga kompromisów. Nie wszystko musi być idealne od początku. Kluczowe pytanie przy skalowaniu brzmi: który dług techniczny warto zatrzymać, a który natychmiast spłacić? Odpowiedź zależy od kontekstu biznesowego, nie od czystości kodu.

Kluczowe jest rozróżnienie między świadomym a nieświadomym długiem. Świadomy dług zaciągasz, gdy wiesz, co robisz i masz plan spłaty. Zespół decyduje razem, zapisuje decyzję i wraca do niej później. Taki dług rzadko staje się problemem, bo jest pod kontrolą.

Nieświadomy dług powstaje, gdy programista pod presją wybiera skrót i nie mówi o tym zespołowi. „Naprawimy później” zamienia się w „nigdy”. To właśnie nieświadomy dług zamienia normalny kod w legacy code. Kompromis za kompromisem powstaje system, którego nikt nie rozumie.

Według badań McKinsey dług techniczny stanowi od 20% do 40% wartości majątku technologicznego firmy. Dla organizacji z majątkiem IT wartym 10 milionów złotych oznacza to 2-4 miliony zamrożonej wartości. To nie „drobny problem techniczny”. To fundamentalne obciążenie, które bezpośrednio przekłada się na ilość legacy code w organizacji.

Koszty legacy code: ukryte konsekwencje strachu przed zmianą

Legacy code to nie tylko problem programistów. To realne koszty biznesowe, które rosną z czasem.

Ukryte koszty nie pojawiają się w standardowych raportach finansowych. Spowolnienie delivery sprawia, że nowe funkcje zajmują dwa, trzy, pięć razy więcej czasu. Wydłużony czas naprawy błędów oznacza, że zamiast godzin potrzebujesz dni lub tygodni. Trudny onboarding powoduje, że nowi developerzy potrzebują miesięcy zamiast tygodni, by stać się produktywnymi. Rotacja zespołu rośnie, bo frustracja prowadzi do odejść najlepszych ludzi. Utracone szanse biznesowe mnożą się, bo konkurencja wyprzedza, podczas gdy Ty „gasisz pożary”.

Punkt krytyczny następuje, gdy każda zmiana wprowadza nowy błąd. Osiągasz stan, gdzie każdy ruch powoduje regresję. Zespół boi się dotykać kodu. Nawet drobne zmiany stają się ryzykowne i wymagają rozbudowanych testów manualnych. Organizacja traci zdolność do reagowania na zmiany rynkowe.

To moment, gdy często pada hasło „przepiszmy wszystko od nowa”. Frustracja jest zrozumiała. Ale ta droga prowadzi do jeszcze większych problemów.

Modernizacja legacy code: metoda Strangler Fig zamiast przepisywania

„Big Bang Rewrite” (przepisanie od zera) to pułapka, w którą wpadło wiele firm. Stopniowa modernizacja metodą Strangler Fig minimalizuje ryzyko i pozwala czerpać wartość już w trakcie procesu.

Przepisywanie od zera zazwyczaj kończy się katastrofą. Wymiana poważnego systemu IT zajmuje lata, nie miesiące. Użytkownicy nie mogą czekać na nowe funkcje, bo konkurencja nie śpi. Trudno ustalić wszystkie szczegóły istniejącego zachowania, bo dokumentacja kłamie lub nie istnieje. Część zachowań okazuje się niepotrzebna, więc budowanie ich od nowa to czyste marnotrawstwo. Przez cały czas utrzymujesz dwa systemy, co generuje podwójny koszt.

Martin Fowler zaproponował alternatywę inspirowaną naturą: metodę Strangler Fig (figowiec dusiciel). Ta roślina z lasów Queensland rośnie wokół drzewa-gospodarza, aż w końcu je zastępuje. Podobnie działa modernizacja IT: nowe funkcje budujesz w nowym systemie, stopniowo przenosisz istniejące zachowania, a stary system „obumiera” kawałek po kawałku.

Skuteczna modernizacja opiera się na czterech filarach:

  • Zrozum cele. Krystalicznie jasne pożądane rezultaty są niezbędne. Różne grupy muszą chcieć tego samego.
  • Podziel problem. Znajdź naturalne granice w systemie, które pozwolą wydzielić niezależne części.
  • Dostarczaj małymi krokami. Małe komponenty oznaczają mniejsze ryzyko i wcześniejszą wartość biznesową.
  • Zmień organizację. Bez zmiany kultury i procesów nowe systemy skończą tak samo jak stare.

Architektura przejściowa może wyglądać jak „tymczasowy bałagan”. Ale to planowane rusztowanie – zmniejsza ryzyko i pozwala czerpać wartość już w trakcie modernizacji.

Od czego zacząć: praktyczne kroki zarządzania legacy code

Zamiast walczyć z legacy code, zbuduj systematyczny proces zarządzania nim i długiem technicznym, który go napędza. Zacznij od diagnozy i małych, bezpiecznych kroków.

Diagnoza wymaga szczerości. Zidentyfikuj obszary kodu, które budzą największy strach w zespole. Zapytaj wprost: „którego modułu najbardziej nie chcecie dotykać?”. Zmapuj, które części systemu zmieniają się najczęściej i powodują najwięcej problemów. Oceń, gdzie brak testów najbardziej blokuje zmiany. Te trzy informacje pokażą, gdzie zacząć.

Pierwsze kroki powinny budować bezpieczeństwo, nie zmieniać funkcjonalność. Zacznij od testów charakteryzacyjnych (characterization tests). Opisują one, co kod robi, nie co powinien robić. Wydziel granice między modułami tam, gdzie planujesz zmiany. Dokumentuj decyzje – Ty z przyszłości będziesz wdzięczny.

Kultura ciągłego doskonalenia wymaga regularności. Przeznaczaj stały czas na redukcję długu, na przykład 20% każdego sprintu. Definition of Done powinno chronić przed nieświadomym dodawaniem nowego długu. Retrospektywy techniczne pozwalają pytać: co utrudnia nam pracę i jak to naprawić?

Sygnały ostrzegawcze wymagają natychmiastowej reakcji. Każda zmiana w module X powoduje błędy w module Y. Onboarding nowego developera trwa ponad trzy miesiące. Zespół unika pewnych części kodu, „bo lepiej nie ruszać”. Czas dostarczenia prostych funkcji rośnie z miesiąca na miesiąc. Jeśli rozpoznajesz te wzorce, działaj teraz.

Legacy code: kluczowe wnioski i następne kroki

Legacy code to nie wróg, ale wyzwanie. Wymaga świadomego zarządzania, nie unikania. Strach przed zmianą można pokonać przez zrozumienie kodu, budowanie testów i stopniową modernizację.

Kluczowe wnioski z tego artykułu: legacy code to wartościowy kod, którego boisz się zmienić, a wiek nie ma znaczenia. Strach przed zmianą bierze się z nagromadzonego długu technicznego, który narastał przez lata nieświadomych kompromisów. „Big Bang Rewrite” to pułapka, a metoda Strangler Fig to bezpieczniejsza droga. Przejrzystość, regularna spłata długu i kultura ciągłego doskonalenia zapobiegają przekształceniu normalnego kodu w legacy.

Zamiast czekać na „wielką modernizację”, zacznij dziś od małego kroku. Zidentyfikuj jeden obszar kodu, który budzi największy strach w zespole. Napisz dla niego pierwszy test charakteryzacyjny (characterization test). To początek drogi od strachu do kontroli nad własnym kodem.

Źródła

  • https://understandlegacycode.com/blog/what-is-legacy-code-is-it-code-without-tests/
  • https://martinfowler.com/bliki/StranglerFigApplication.html
  • https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/tech-debt-reclaiming-tech-equity
  • https://www.qagile.pl/scrum/dlug-techniczny-ukryty-koszt-szybkosci-agile/

Materiał Partnera

Autor

Moje teksty

Hej, jestem Sebastian! Technologia to mój świat – świetnie ogarniam laptopy, komputery i smartfony, bo od zawsze lubiłem rozkręcać sprzęty i sprawdzać, co potrafią. Uwielbiam testować nowinki, porównywać różne modele i szukać najlepszych rozwiązań. Zawsze mam sporo praktycznych wskazówek i fajnych trików, którymi chętnie się podzielę! Jeśli masz pytania, śmiało pytaj – [email protected]