Legacy — není jen starý kód. Je to fungující systém, který firmě vydělává peníze, ale brzdí rozvoj. Ve vývoji mobilních aplikací může být legacy napsáno v Objective-C, používat zastaralé knihovny nebo architektonické vzory. Podle zprávy CAST Software (2024) průměrné stáří řádku kódu v enterprise projektech přesahuje 14 let. Strategie práce s legacy rozhoduje o tom, zda se stane brzdou nebo zůstane řiditelným aktivem.
Hlavní body
Legacy — kód nebo systém, který nadále funguje v produkci, ale již nesplňuje moderní standardy kvality. Legacy může být napsáno v zastaralém jazyce (např. Objective-C místo Swift), používat nepodporované knihovny nebo architektonické vzory, které jsou dávno považovány za antivzory.
Klíčovou vlastností legacy je nedostatek testů. Podle definice Michaela Featherse (2004) je legacy kód kód bez testů. Pokud nelze chování bezpečně změnit, systém je ve statusu legacy bez ohledu na stáří. Čerstvý kód bez unit testů — to je legacy prvního dne.
Legacy není nutně špatné. Dobře navržený systém v Java 8 může být spolehlivější a srozumitelnější než chaotický kód v Kotlinu s korutinami. Stáří kódu není ukazatelem kvality — důležité je, jak snadno systém podléhá změnám a rozšiřování.
Každý úspěšný systém se časem stává legacy. To je přirozený proces: technologie se vyvíjejí rychleji, než může být kód přepsán. Aplikace napsaná před 5 lety ve Swift 2 je dnes legacy, i když v okamžiku vzniku byla moderní.
Obchodní hodnota legacy je často podceňována. Systém stabilně funguje, zpracovává transakce, ukládá data — přepisování přináší rizika. Podle Standish Group (2024) 35% projektů úplného přepsání končí neúspěchem. Ekonomicky není zbavení se legacy ospravedlnitelné, ale naučit se s ním pracovat.
Nejlepší strategie — postupná migrace, zapouzdření starého kódu za nová rozhraní a automatizované testování. Legacy se stává problémem pouze tehdy, když přestane podléhat změnám s předvídatelnými náklady.
Nedostatek automatických testů — hlavní indikátor. Pokud po změně jednoho řádku kódu programátor nemůže spustit testy a ujistit se, že se nic nerozbilo — máte co do činění s legacy. Další znak: postup nasazení trvá hodiny a vyžaduje ruční zásahy.
Dokumentace neodpovídá kódu — další marker. Architektonické diagramy jsou zastaralé, komentáře popisují chování, které se již změnilo. Time-to-ramp-up pro nového programátora přesahuje měsíc — znak vysoké složitosti a nízké udržovatelnosti systému.
Další znaky: monolitická architektura bez jasných hranic, ruční testování jako hlavní metoda ověřování, dlouhý CI pipeline (více než 30 minut), používání knihoven bez aktuálních verzí a nemožnost aktualizovat závislosti bez rozbití sousedních modulů.
Fenomén „křehkého kódu” — změna na jednom místě rozbije tři další. To je důsledek těsného provázání (tight coupling), kdy moduly o sobě vědí příliš mnoho. Čím vyšší je coupling, tím rychleji systém přechází do kategorie legacy.
Snižení rychlosti — hlavní riziko. Přidání jednoduché funkce vyžaduje hodiny studia kódu a dny testování. Podle Stripe (2024) tráví programátoři 33% času překonáváním technického dluhu, který přímo souvisí s přítomností legacy modulů v projektu.
Únik expertízy — autoři původního kódu odcházejí ze společnosti a dokumentace je neúplná. Noví programátoři se bojí dotýkat nepochopitelných modulů, což vede k efektu „zmrzlého kódu”: modul se nevyvíjí, ale nadále funguje. Bus factor takových systémů je kriticky nízký.
Bezpečnost — zastaralé knihovny obsahují známé zranitelnosti. Používání OpenSSL 1.0.2 nebo zastaralých verzí Jacksonu v Java projektech je přímou cestou k bezpečnostním incidentům, které mohou firmu stát reputaci a zákazníky.
Demotivace týmu — práce s legacy bez strategie jeho zlepšování snižuje spokojenost programátorů. Tým přestává být hrdý na produkt, fluktuace roste, což dále zpomaluje vývoj systému.
Charakterizační testy — první krok před jakoukoli změnou legacy kódu. Spusť kód na známých vstupních datech a zaznamenej očekávaný výstup. Tyto testy zachycují aktuální chování jako specifikaci. Golden master testing — varianta, kdy se výstupní data porovnávají s referenčním souborem.
Seam analýza — hledání bodů, kde lze přerušit provázání bez změny chování. Michael Feathers rozlišuje několik typů seam: preprocessor seam, object seam, link seam. Object seam — nejběžnější: nahrazení skutečného objektu testovacím stubem přes rozhraní.
Sprout method a Sprout class — techniky přidávání nového kódu vedle starého, ne uvnitř něj. Místo úpravy existující metody vytvoř novou metodu s potřebnou logikou a volej ji ze staré. Tím se minimalizuje riziko rozbití fungujícího kódu.
class LegacyPaymentProcessor {
def process(payment) {
// 200 řádků legacy kódu, kterých by se nemělo dotýkat
logPayment(payment) // sprout method
}
def logPayment(payment) {
// nový kód přidaný vedle legacy
}
}
Vzor Strangler Fig — doporučený přístup pro migraci legacy. Nový modul je vytvářen paralelně, provoz je postupně přepínán ze starého na nový. Starý modul přirozeně „umírá”, když přestane dostávat požadavky. Vzor minimalizuje rizika a umožňuje návrat v případě problémů.
Branch by Abstraction — technika, při které se vytváří abstrakce nad starou a novou implementací. Klientský kód přechází na abstrakci, stará implementace je postupně nahrazována novou. Příklad: nahrazení síťové vrstvy z AFNetworking na Alamofire přes jednotný protokol NetworkService.
Postupná migrace — rozdělení přechodu na malé kroky: zapouzdření starého modulu → psaní testů → vytvoření nového modulu → paralelní spuštění → odstranění starého modulu. Každý krok končí stabilním stavem systému, což umožňuje nasazení změn kdykoli.
Často kladené otázky
Úplné přepsání je nejrizikovější možnost. Pouze 25% projektů Big Rewrite je úspěšně dokončeno včas. Lepší je aplikovat vzor Strangler Fig: vyměňuj moduly postupně bez zastavení produktu. Každá iterace přináší obchodní hodnotu a rizika se rozloží v čase.
Začni charakterizačními testy: spusť modul na známých datech, zaznamenej výsledek. Golden master testing — jednoduchý způsob, jak zachytit chování. Přidávej testy pokaždé, když se dotkneš řádku kódu. Za 6 měsíců budeš mít kostru chránící před regresemi.
Pokud je systém stabilní, nevyžaduje časté změny a neovlivňuje rychlost vývoje ostatních modulů — nech ho být. „If it ain’t broken, don’t fix it” — rozumný přístup pro izolované legacy moduly s nízkou frekvencí změn. Kód se dotýkej jen tehdy, když je potřeba provést obchodní změny.
Používej sémantické verzování a aktualizuj postupně: patch → minor → major. Pro každou knihovnu piš testy kompatibility. Dependabot nebo Renovate automatizují vytváření PR pro aktualizace. Pokud je knihovna deprecated — naplánuj náhradu přes abstrakci.
Technický dluh — metafora pro odhad nákladů na odložená vylepšení. Legacy — konkrétní systém nebo kód, který již zastaral. Technický dluh se může nahromadit za měsíc, legacy vyžaduje čas. Ne každý technický dluh se stane legacy, ale každé legacy obsahuje technický dluh.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také