ix
ix

informatix

EN version Porozmawiajmy o projekcie
Strona główna / Blog / Legacy code — co to jest i kiedy naprawdę trzeba go ruszyć
• 9 min czytania •

Legacy code — co to jest i kiedy naprawdę trzeba go ruszyć

Legacy code to nie „stary kod", ale kod, w którym koszt zmiany przewyższa wartość zmiany. Definicja, trzy objawy, koszt ekonomiczny i kryteria decyzji o modernizacji.

Legacy code to kod, który działa i zarabia, ale którego nikt nie chce dotykać — bo każda zmiana grozi awarią, a nikt nie potrafi przewidzieć skutków. Definicja nie mówi nic o wieku kodu ani o technologii. Mówi o koszcie zmiany: jeśli modyfikacja, która powinna zająć dzień, zajmuje trzy tygodnie i kończy się regresją w innym module, masz legacy code — niezależnie od tego, czy napisano go w PHP 5, czy w Laravelu 10.

Najważniejsze: Legacy code to nie „stary kod" — to kod, w którym koszt zmiany przewyższa wartość zmiany. Trzy objawy: nie da się go bezpiecznie zmienić (brak testów), nie da się go zrozumieć (brak dokumentacji i wiedzy w zespole) i nie da się go uruchomić lokalnie (zależność od jednego środowiska). Kluczowa konsekwencja: legacy to problem ekonomiczny, nie techniczny — więc decyzję o modernizacji podejmuje się na podstawie liczb, nie opinii o „brzydkim kodzie".

  • ## Definicja: czym legacy code naprawdę jest

Najczęściej cytowana definicja mówi, że legacy code to kod bez testów. To trafne, ale niepełne. Pełniejsza wersja brzmi: legacy code to kod, w którym koszt wprowadzenia zmiany jest nieproporcjonalnie wysoki względem wartości tej zmiany.

  • Wynika z tego coś ważnego: ten sam kod może być legacy dla jednej firmy i zupełnie znośny dla innej. System, którego nie rozwijasz, nie jest legacy — nie ma znaczenia, jak wygląda w środku, dopóki nikt go nie zmienia. Legacy staje się problemem w momencie, gdy biznes potrzebuje zmian, a kod nie pozwala ich dostarczyć w akceptowalnym czasie.

Z tego powodu „przepiszmy to, bo jest stare" jest złym argumentem. Argumentem jest: „ta zmiana zajmuje nam trzy tygodnie zamiast dwóch dni" albo „boimy się wdrożyć w piątek".

Trzy objawy, które definiują legacy

1. Nie da się bezpiecznie zmienić. Nie ma testów, więc każda zmiana to ryzyko regresji. Zespół wdraża w oknach serwisowych, w piątek po godzinach albo wcale. Pojawia się zjawisko, które nazywam zamrażaniem: kod działa, więc nikt go nie rusza, więc dług rośnie.

2. Nie da się zrozumieć. Brak dokumentacji, brak wiedzy w zespole, brak historii decyzji. Osoba, która napisała kluczowy moduł, odeszła trzy lata temu. Nowy programista potrzebuje tygodni, żeby zrobić pierwszą zmianę — a i tak robi ją metodą prób i błędów.

3. Nie da się uruchomić lokalnie. Aplikacja działa tylko na jednym serwerze produkcyjnym, z bazą, do której nikt nie ma kopii, i z zależnościami, których nie da się odtworzyć. Efekt: nie ma środowiska testowego, więc każda zmiana idzie prosto na produkcję.

Te trzy objawy zwykle występują razem — i razem tworzą pułapkę: nie możesz bezpiecznie zmieniać, bo nie rozumiesz; nie rozumiesz, bo nie możesz uruchomić; nie możesz uruchomić, bo nikt nie przygotował środowiska.

Czego legacy NIE oznacza

Legacy to nie wiek. System napisany pięć lat temu bez testów jest legacy. System napisany piętnaście lat temu z testami i dokumentacją nie jest. Wiek koreluje z problemem, ale go nie definiuje.

Legacy to nie technologia. PHP 5.6 to realne ryzyko bezpieczeństwa (brak wsparcia), ale to osobny problem. Kod w PHP 8.3 może być legacy, jeśli nie da się go zmienić. Kod w PHP 5.6 może być znośny, jeśli jest zamrożony i nikt go nie dotyka — choć wtedy problemem staje się bezpieczeństwo, a nie utrzymanie.

Legacy to nie „brzydki kod". Nieczytelny kod jest kosztowny, ale dopóki zmiany są szybkie i bezpieczne, nie ma powodu go przepisywać. Estetyka nie jest kryterium biznesowym.

Legacy to nie wyrok. Większość systemów da się doprowadzić do stanu, w którym zmiany są przewidywalne — bez przepisywania od zera. To zwykle kwestia dodania testów wokół krytycznych ścieżek, odtworzenia środowiska i uporządkowania zależności.

Dlaczego to problem ekonomiczny

  • Policz to tak: ile zmian rocznie próbujesz wprowadzić i ile z nich zajmuje dłużej, niż powinno? Jeśli masz 20 zmian rocznie, każda przeciąga się o tydzień, a tydzień pracy zespołu kosztuje 8 000 zł — to 160 000 zł rocznie wydane na walkę z kodem, a nie na rozwój produktu.

Do tego dochodzi koszt, którego nie widać w budżecie: zmiany, których nie wprowadzasz, bo się boisz. Funkcje odłożone „na po modernizacji", integracje, które „zrobimy później", wejście na nowy kanał sprzedaży, który „wymaga przebudowy". Ten koszt jest zwykle większy niż koszt samej modernizacji — ale nie pojawia się w żadnym raporcie, bo to koszt alternatywny.

Trzecia pozycja to ryzyko. System bez testów i bez środowiska testowego w końcu zawodzi — i zawodzi w najmniej odpowiednim momencie. Koszt przestoju zależy od tego, co system obsługuje: przy sklepie liczy się w utraconych zamówieniach, przy systemie wewnętrznym w godzinach przestoju zespołu.

Kiedy modernizować, a kiedy nie

Modernizuj, gdy:

  • koszt zmian blokuje rozwój biznesu (nie da się dostarczyć funkcji, których potrzebujesz),
  • zbliża się wymóg zewnętrzny: koniec wsparcia PHP, zmiana API w systemie, z którym się integrujesz, wymóg audytu,
  • ryzyko awarii jest nieakceptowalne (system obsługuje sprzedaż lub dane krytyczne),
  • kluczowa wiedza wychodzi z firmy razem z osobą.

Nie modernizuj, gdy:

  • system działa i nie planujesz w nim zmian (zamrożony system to nie problem — to koszt, który już poniosłeś),
  • nie masz właściciela projektu po stronie biznesu (modernizacja bez decydenta kończy się przepisaniem tego samego),
  • liczysz na to, że przepisanie „przy okazji" doda funkcje (to najczęstsza przyczyna przekroczenia budżetu — najpierw odtwórz działanie, potem rozwijaj),
  • koszt modernizacji przewyższa koszt utrzymania obecnego stanu przez najbliższe 3 lata.

Ostatni punkt wymaga liczby. Dlatego modernizację zaczyna się od audytu, nie od decyzji o przepisaniu.

Co zawiera audyt i co z niego wynika

Audyt techniczny to nie „przegląd kodu". To odpowiedź na cztery pytania

  1. Co ten system robi — mapa funkcji i przepływów danych, w tym integracji z systemami zewnętrznymi.
  2. Co jest krytyczne — które ścieżki obsługują przychód lub dane krytyczne, a które można zamrozić.
  3. Dlaczego zmiany są wolne — gdzie dokładnie traci się czas: brak testów, splątane zależności, niejasna architektura, brak środowiska.
  4. Ile kosztuje wyjście — warianty: dodać testy i środowisko (najtańsze), zrefaktoryzować moduły krytyczne (średnie), przepisać wybrane komponenty (droższe), przepisać całość (najdroższe i najrzadziej uzasadnione).

Dopiero z tymi czterema odpowiedziami da się policzyć zwrot i wybrać zakres. Audyt kosztuje ułamek modernizacji, a bez niego każda decyzja jest zgadywaniem.

Najczęściej zadawane pytania

Co to jest legacy code w jednym zdaniu?

Legacy code to działający kod, w którym koszt wprowadzenia zmiany przewyższa wartość tej zmiany — najczęściej dlatego, że brakuje testów, dokumentacji i możliwości uruchomienia go poza produkcją.

Czy legacy code to zawsze stary kod?

Nie. Wiek koreluje z problemem, ale go nie definiuje. Kod napisany rok temu bez testów i bez środowiska lokalnego jest legacy. Kod sprzed piętnastu lat, pokryty testami i z jasną architekturą, nie jest — nawet jeśli wygląda staro.

Jak poznać, że mam legacy code?

  • Trzy pytania kontrolne: czy możesz bezpiecznie wdrożyć zmianę w piątek po południu? Czy nowy programista zrobi pierwszą zmianę w ciągu tygodnia? Czy możesz uruchomić system lokalnie? Jeśli na którekolwiek odpowiadasz „nie", masz legacy — niezależnie od technologii.

Czy trzeba przepisać system od zera?

Prawie nigdy w całości. Najskuteczniejsze podejście to modernizacja przyrostowa: odtworzenie środowiska, dodanie testów wokół ścieżek krytycznych, uporządkowanie zależności i refaktoryzacja modułów, które najbardziej blokują zmiany. Przepisanie od zera ma sens tylko wtedy, gdy fundamentu nie da się odtworzyć — a to rzadsze, niż się wydaje.

Ile kosztuje modernizacja legacy?

Zależy od zakresu i zaczyna się od audytu (u mnie 2 000 zł netto). Dalsze etapy: uporządkowanie środowiska i testów, refaktoryzacja modułów krytycznych, modernizacja całych komponentów. Widełki i czynniki wpływające na cenę opisuję osobno w artykule o kosztach modernizacji.

Czy modernizacja wymaga zatrzymania systemu?

Nie. Modernizację prowadzi się równolegle do działania systemu, na kopii środowiska, z przełączaniem modułów pojedynczo po testach porównawczych. Przestój występuje tylko wtedy, gdy wymaga go migracja bazy — i wtedy planuje się go na okno o najniższym ruchu.

Źródła i narzędzia

👉 Podejrzewasz, że masz legacy code i nie wiesz, od czego zacząć? Zobacz usługę modernizacji i utrzymania kodu — zaczynamy od audytu, który daje listę priorytetów i wycenę, a nie od razu przepisanie. Napisz przez formularz kontaktowy lub na kontakt@informatix.com.pl.

👉 Potrzebujesz stałej opieki zamiast jednorazowego projektu? Zobacz opiekę techniczną z SLA. Jeśli interesują Cię widełki, zajrzyj do cennika.

📖 Zobacz również: Modernizacja legacy code — plan działania krok po kroku, ile kosztuje modernizacja legacy oraz refaktoryzacja czy przepisanie od zera.

Powiązane wpisy