„Refaktoryzacja czy przepisanie od zera" to najdroższe pytanie w projekcie legacy — bo odpowiedź „przepisujemy" oznacza zwykle dwukrotnie wyższy budżet i dwa razy dłuższy czas. A mimo to jest to domyślna odpowiedź, jakiej udziela większość zespołów, gdy kod jest wystarczająco przerażający. Ten artykuł pokazuje kryteria decyzyjne, które da się zastosować bez emocji, i wyjaśnia, dlaczego wariant pośredni wygrywa najczęściej.
Najważniejsze: Refaktoryzacja (przebudowa istniejącego kodu) wygrywa w około 80% przypadków: jest tańsza, nie wymaga dwóch systemów równolegle i nie gubi wiedzy zapisanej w starym kodzie — włącznie z regułami biznesowymi, których nikt już nie pamięta. Przepisanie od zera jest uzasadnione tylko wtedy, gdy spełnione są co najmniej dwa warunki: technologia nie ma wsparcia i nie da się jej utrzymać, system nie ma wartościowej logiki biznesowej do zachowania, biznes może poczekać na pełne odtworzenie funkcji, a zespół ma wiedzę domenową niezależną od kodu. Decyzję podejmuje się po audycie, nie przed nim.
Na czym polega różnica
Refaktoryzacja to zmiana struktury kodu bez zmiany jego zachowania. W praktyce modernizacja przyrostowa: odtworzenie środowiska, dodanie testów wokół ścieżek krytycznych, przebudowa najbardziej problematycznych modułów, aktualizacja zależności. System działa przez cały czas, a zmiany wchodzą stopniowo.
Przepisanie od zera to zbudowanie nowego systemu od podstaw i zastąpienie starego. Brzmi prościej, ale ma konsekwencję, o której mówi się rzadko: przez cały czas trwania projektu masz dwa systemy — stary, który działa i wymaga utrzymania, oraz nowy, który jeszcze nie działa. To podwaja koszt operacyjny i wydłuża projekt.
Dlaczego przepisanie jest pułapką
1. Wiedza jest w kodzie, nie w dokumentacji. Stary system zawiera setki decyzji biznesowych, których nikt nie zapisał: wyjątki w regułach cenowych, obejścia dla konkretnych klientów, zależności między modułami, które „muszą" działać w określonej kolejności. Przepisanie od zera oznacza odkrycie ich wszystkich na nowo — a część odkryjesz dopiero wtedy, gdy klient zgłosi, że „to działało inaczej".
2. Zakres rośnie w trakcie. Nowy system buduje się „czysty", więc naturalnie chce się dodać rzeczy, których w starym nie było. To najczęstsza przyczyna przekroczenia budżetu — i najtrudniejsza do kontrolowania, bo każda nowa funkcja wydaje się wtedy tania.
3. Okres dwóch systemów jest drogi. Przez cały projekt utrzymujesz stary system (bo obsługuje biznes) i budujesz nowy. To nie jedna inwestycja, ale dwie równolegle — plus praca nad migracją danych, która sama bywa osobnym projektem.
4. Ryzyko jest skumulowane na końcu. Przy refaktoryzacji ryzyko rozkłada się na małe kroki: każdy moduł testujesz osobno i możesz się wycofać. Przy przepisaniu całe ryzyko spada w momencie przełączenia — a to najgorszy moment, bo wtedy nie ma już drogi powrotu bez utraty pracy.
5. Projekty przepisania trwają dłużej niż zakładano. To prawidłowość, nie pech. Powód jest strukturalny: szacujesz czas budowy nowego systemu, ale nie szacujesz czasu odkrywania wiedzy ukrytej w starym.
Kiedy przepisanie od zera MA sens
Nie jest to nigdy decyzja lekka. Uzasadniona jest w tych przypadkach
-
Technologia bez wsparcia i bez drogi migracji. PHP 5.x bez wsparcia bezpieczeństwa, framework porzucony przez autorów, baza danych bez możliwości aktualizacji. Jeśli nie ma ścieżki aktualizacji, refaktoryzacja nie ma punktu zaczepienia.
-
System nie zawiera wartościowej logiki. Narzędzie wewnętrzne, prototyp, system, który „robi jedną rzecz" i robi ją źle. Jeśli nie ma czego zachować, nie ma czego refaktoryzować.
-
Fundament jest błędny, nie tylko stary. Architektura uniemożliwia spełnienie wymogu regulacyjnego albo wydajnościowego, którego nie da się obejść — np. system nie da się rozdzielić na moduły, bo jest jednym splątanym monolitom bez granic.
-
Skala problemu przewyższa koszt przepisania. Jeśli 80% kodu wymaga przebudowy, a nie 20%, rachunek może przechylić się na stronę nowego systemu.
-
Masz wiedzę domenową niezależnie od kodu. Zespół rozumie proces biznesowy na tyle, że potrafi zweryfikować nowy system bez porównywania go ze starym.
-
Zwróć uwagę: to lista warunków, nie pojedynczy powód. Jeden z nich rzadko wystarcza.
Wariant pośredni, który wygrywa najczęściej
Zamiast wybierać między „wszystko refaktoryzujemy" a „wszystko przepisujemy", stosuje się podejście warstwowe
Krok 1 — zamrożenie i odtworzenie. Odtwórz środowisko lokalne, wprowadź kontrolę wersji, skonfiguruj kopie zapasowe i CI. To warunek wstępny wszystkiego dalszego i zwykle rozwiązuje część problemu samo w sobie.
Krok 2 — testy wokół ścieżek krytycznych. Nie testuj wszystkiego — pokryj testami to, co obsługuje przychód lub dane krytyczne. Te testy staną się siatką bezpieczeństwa dla każdej dalszej zmiany.
Krok 3 — refaktoryzacja modułów blokujących. Zidentyfikuj 20% kodu, który powoduje 80% problemów z wdrożeniami, i przebuduj je pojedynczo, za testami.
Krok 4 — wymiana komponentów. Tam, gdzie refaktoryzacja jest nieopłacalna (moduł jest zbyt splątany, technologia zbyt przestarzała), zastąp komponent nowym — ale przez granicę, którą da się testować osobno. Wzorzec „figi dusiciela": nowy komponent przejmuje funkcję stopniowo, stary działa do momentu, gdy nowy jest sprawdzony.
Krok 5 — decyzja o reszcie. Po krokach 1–4 okazuje się zwykle, że pozostała część systemu nie wymaga już niczego. Zamrożony, działający moduł, którego nikt nie zmienia, nie jest problemem — niezależnie od tego, jak wygląda w środku.
Ta ścieżka nie wymaga decyzji „wszystko albo nic" na starcie. Każdy krok daje wartość samodzielnie i można się zatrzymać w dowolnym momencie.
Tabela decyzyjna
| Kryterium | Refaktoryzacja | Przepisanie od zera |
|---|---|---|
| Kod ma wartość biznesową, której nie znasz w całości | ✓ wygrywa | ryzyko utraty wiedzy |
| Technologia ma wsparcie i ścieżkę aktualizacji | ✓ wygrywa | nieuzasadnione |
| Technologia bez wsparcia i bez drogi migracji | trudne | ✓ może wygrać |
| Możesz wdrażać zmiany stopniowo | ✓ wygrywa | niepotrzebne ryzyko |
| Nie możesz zatrzymać systemu na czas projektu | ✓ wygrywa | wymaga dwóch systemów |
| System jest prototypem bez wartościowej logiki | nieuzasadnione | ✓ wygrywa |
| Budżet i czas są ograniczone | ✓ wygrywa | ryzyko przekroczenia |
| Zespół zna domenę niezależnie od kodu | możliwe | ✓ bardziej realne |
Jak podjąć decyzję w praktyce
Nie decyduj przed audytem. Audyt odpowiada na pytanie, ile kodu naprawdę wymaga przebudowy: 20% czy 80%. To jedyna liczba, która realnie rozstrzyga wybór.
Policz oba warianty w pieniądzach i czasie. Refaktoryzacja: koszt etapowy + utrzymanie starego systemu w trakcie. Przepisanie: koszt budowy + utrzymanie obu systemów przez cały projekt + koszt migracji danych + ryzyko opóźnienia. W większości przypadków pierwsza liczba jest niższa, a różnica rośnie złożonością systemu.
Zapytaj o koszt błędu. Co się stanie, jeśli nowy system nie odtworzy jakiejś funkcji?
Przy refaktoryzacji cofasz jeden moduł. Przy przepisaniu cofasz cały projekt albo łatasz nowy system pod presją.
Sprawdź, czy zespół ma wiedzę niezależną od kodu. Jeśli jedynym źródłem prawdy o procesach jest stary kod, przepisanie oznacza, że tę wiedzę trzeba wydobyć w trakcie projektu — a to praca, której nikt nie szacuje.
Najczęściej zadawane pytania
Refaktoryzacja czy przepisanie — co wybrać?
W około 80% przypadków refaktoryzacja. Przepisanie od zera ma sens, gdy spełnione są co najmniej dwa warunki: technologia nie ma wsparcia i drogi migracji, system nie zawiera wartościowej logiki, fundament jest błędny (nie tylko stary), skala przebudowy przekracza 80% kodu, a zespół ma wiedzę domenową niezależnie od kodu.
Czy przepisanie od zera nie jest szybsze?
Nie — i to najczęstsze nieporozumienie. Budowa nowego systemu jest może szybsza niż refaktoryzacja „od zera do ideału", ale dochodzi czas na odkrycie wiedzy ukrytej w starym kodzie, migrację danych i utrzymanie dwóch systemów równolegle. Projekty przepisania regularnie trwają dłużej niż zakładano, bo szacuje się budowę, a nie odkrywanie.
Czy refaktoryzacja jest tańsza?
Zwykle tak, i to znacznie. Główna różnica nie leży w stawce godzinowej, ale w tym, że refaktoryzacja nie wymaga utrzymywania dwóch systemów jednocześnie ani pełnej migracji danych na końcu. Dodatkowo rozkłada ryzyko na małe kroki, z których każdy można zatrzymać.
Co to jest wzorzec „figi dusiciela"?
To strategia modernizacji przyrostowej: nowy komponent przejmuje funkcję stopniowo, a stary działa równolegle do momentu, gdy nowy jest w pełni sprawdzony. Nazwa pochodzi od figi, która oplata drzewo i stopniowo je zastępuje. Pozwala modernizować system bez okna serwisowego i bez ryzyka skumulowanego na końcu projektu.
Ile trwa refaktoryzacja, a ile przepisanie?
Refaktoryzacja modułów krytycznych: 1–4 miesiące. Przepisanie systemu o porównywalnym zakresie: 3–12 miesięcy, plus okres równoległego działania obu systemów. Przy systemach z wieloma integracjami zewnętrznymi czas bywa dłuższy w obu wariantach, ale w przepisaniu rośnie szybciej.
Czy da się zmienić decyzję w trakcie projektu?
Przy refaktoryzacji tak — to jedna z jej głównych zalet. Jeśli po uporządkowaniu środowiska i testów okaże się, że część modułów trzeba wymienić, robi się to komponent po komponencie. Przy przepisaniu zmiana decyzji oznacza utratę pracy włożonej w nowy system.
Źródła i narzędzia
- Martin Fowler — Strangler Fig Application
- Martin Fowler — Refactoring (definicja i katalog)
- Michael Feathers — Working Effectively with Legacy Code
- Joel Spolsky — Things You Should Never Do (o przepisywaniu od zera)
👉 Stoisz przed decyzją o modernizacji? Zobacz usługę modernizacji i utrzymania kodu — audyt daje odpowiedź, ile kodu naprawdę wymaga przebudowy, i dopiero na tej podstawie wybieramy wariant. Napisz przez formularz kontaktowy lub na kontakt@informatix.com.pl.
📖 Zobacz również: Legacy code — co to jest, ile kosztuje modernizacja legacy oraz modernizacja legacy code — plan działania.