Legacy inom apputveckling — vad det är, risker och strategier

Författare: IT Sectr Publicerad: 2026-07-27 Lästid: 7 min

Legacy — är inte bara gammal kod. Det är ett fungerande system som tjänar pengar åt verksamheten men bromsar utvecklingen. Inom mobilapputveckling kan legacy vara skrivet i Objective-C, använda föråldrade bibliotek eller arkitekturmönster. Enligt rapporten från CAST Software (2024) överstiger medelåldern för en kodrad i enterprise-projekt 14 år. Strategin för att arbeta med legacy avgör om det blir en broms eller förblir en hanterbar tillgång.

Huvudpunkter

  • Legacy — kod som fungerar i produktion men använder föråldrad teknik eller metoder
  • Underhåll av legacy kräver förståelse för historiska beslut och noggrann refaktorisering
  • Migreringsstrategi — gradvis ersättning av moduler utan att stoppa produkten via Strangler Fig
  • Testning av legacy — karaktäriseringstester fångar nuvarande beteende före refaktorisering
  • Kodens ålder är i sig inget problem — problemet är bristen på tester och arkitektonisk vision

Vad är legacy inom apputveckling

Legacy — kod eller system som fortfarande fungerar i produktion men inte längre uppfyller moderna kvalitetsstandarder. Legacy kan vara skrivet på ett föråldrat språk (t.ex. Objective-C istället för Swift), använda icke-understödda bibliotek eller arkitekturmönster som länge ansetts vara anti-mönster.

Den viktigaste egenskapen hos legacy är avsaknaden av tester. Enligt definitionen av Michael Feathers (2004) är legacy-kod kod utan tester. Om beteendet inte kan ändras säkert är systemet i legacy-status oavsett ålder. Färsk kod utan enhetstester — är legacy från dag ett.

Legacy är inte nödvändigtvis dåligt. Ett väldesignat system i Java 8 kan vara mer pålitligt och begripligt än kaotisk kod i Kotlin med coroutines. Kodens ålder är ingen kvalitetsindikator — det viktiga är hur väl systemet låter sig förändras och utökas.

Varför legacy-kod är normalt

Varje framgångsrikt system blir med tiden legacy. Detta är en naturlig process: teknik utvecklas snabbare än kod kan skrivas om. En app skriven för 5 år sedan i Swift 2 är idag legacy, även om den vid skapandet var modern.

Affärsvärdet av legacy underskattas ofta. Systemet fungerar stabilt, bearbetar transaktioner, lagrar data — omskrivning innebär risker. Enligt Standish Group (2024) misslyckas 35% av kompletta omskrivningsprojekt. Ekonomiskt är det inte motiverat att göra sig av med legacy, utan att lära sig arbeta med det.

De bästa strategierna — gradvis migrering, inkapsling av gammal kod bakom nya gränssnitt och automatiserad testning. Legacy blir bara ett problem när det inte längre låter sig förändras till en förutsägbar kostnad.

Huvudsakliga tecken på ett legacy-system

Brist på automatiska tester — den främsta indikatorn. Om en utvecklare efter att ha ändrat en kodrad inte kan köra testerna och försäkra sig om att inget gått sönder — har du att göra med legacy. Ytterligare tecken: distributionsproceduren tar timmar och kräver manuella åtgärder.

Dokumentationen överensstämmer inte med koden — ytterligare en markör. Arkitekturdiagram är föråldrade, kommentarer beskriver beteende som redan ändrats. Time-to-ramp-up för en ny utvecklare överstiger en månad — tecken på hög komplexitet och låg underhållbarhet i systemet.

Ytterligare tecken: monolitisk arkitektur utan tydliga gränser, manuell testning som huvudsaklig verifieringsmetod, lång CI-pipeline (mer än 30 minuter), användning av bibliotek utan aktuella versioner och oförmåga att uppdatera beroenden utan att bryta intilliggande moduler.

Fenomenet „skör kod” — en förändring på ett ställe bryter tre andra. Detta är en följd av tät koppling (tight coupling), när moduler vet för mycket om varandra. Ju högre koppling, desto snabbare övergår systemet till kategorin legacy.

Risker med att arbeta med föråldrad kod

Minskad hastighet — den främsta risken. Att lägga till en enkel funktion kräver timmar av kodstudier och dagar av testning. Enligt Stripe (2024) lägger utvecklare 33% av sin tid på att övervinna teknisk skuld, vilket är direkt kopplat till förekomsten av legacy-moduler i projektet.

Expertisförlust — författarna till originalkoden lämnar företaget och dokumentationen är ofullständig. Nya utvecklare är rädda för att röra obegripliga moduler, vilket leder till effekten av „frusen kod”: modulen utvecklas inte men fortsätter att fungera. Bus factor för sådana system är kritiskt låg.

Säkerhet — föråldrade bibliotek innehåller kända sårbarheter. Att använda OpenSSL 1.0.2 eller föråldrade versioner av Jackson i Java-projekt är en direkt väg till säkerhetsincidenter som kan kosta verksamheten anseende och kunder.

Demotivering av teamet — arbete med legacy utan strategi för förbättring minskar utvecklarnas tillfredsställelse. Teamet slutar vara stolt över produkten, personalomsättningen ökar, vilket ytterligare saktar ner systemutvecklingen.

Refaktoriseringsstrategier för legacy

Karaktäriseringstester — första steget före varje ändring av legacy-kod. Kör koden på kända indata och registrera förväntad utdata. Dessa tester fångar nuvarande beteende som specifikation. Golden master testing — variant där utdata jämförs med en referensfil.

Seam-analys — sökning efter punkter där koppling kan brytas utan att ändra beteende. Michael Feathers urskiljer flera typer av seam: preprocessor seam, object seam, link seam. Object seam — vanligast: ersättning av verkligt objekt med test-stub via ett gränssnitt.

Sprout method och Sprout class — tekniker för att lägga till ny kod bredvid gammal kod, inte inuti den. Istället för att modifiera en befintlig metod, skapa en ny metod med önskad logik och anropa den från den gamla. Detta minimerar risken att bryta fungerande kod.

Exempel: lägga till loggning i legacy

groovy
class LegacyPaymentProcessor {
    def process(payment) {
        // 200 rader legacy-kod som inte bör röras
        logPayment(payment) // sprout method
    }
    def logPayment(payment) {
        // ny kod tillagd bredvid legacy
    }
}

Migrering till modern teknikstack

Strangler Fig-mönstret — rekommenderad metod för legacy-migrering. Den nya modulen skapas parallellt, trafiken flyttas gradvis från gammal till ny. Den gamla modulen „dör” naturligt när den slutar ta emot förfrågningar. Mönstret minimerar risker och möjliggör återställning vid problem.

Branch by Abstraction — teknik där en abstraktion skapas över gammal och ny implementering. Klientkoden växlar till abstraktionen, den gamla implementeringen ersätts gradvis av den nya. Exempel: ersättning av nätverkslagret från AFNetworking till Alamofire via ett enhetligt protokoll NetworkService.

Stegvis migrering — uppdelning av övergången i små steg: inkapsling av gammal modul → skrivning av tester → skapande av ny modul → parallell körning → borttagning av gammal modul. Varje steg avslutas med stabil systemstatus, vilket möjliggör implementering av ändringar när som helst.

Vanliga frågor

Måste legacy skrivas om helt?

Fullständig omskrivning är det mest riskfyllda alternativet. Endast 25% av projekten Big Rewrite slutförs framgångsrikt i tid. Bättre att tillämpa Strangler Fig-mönstret: byt ut moduler gradvis utan att stoppa produkten. Varje iteration ger affärsvärde och riskerna fördelas över tiden.

Hur påbörjar man refaktorisering av legacy utan tester?

Börja med karaktäriseringstester: kör modulen på känd data, registrera resultatet. Golden master testing — enkelt sätt att fånga beteende. Lägg till tester varje gång du rör en kodrad. Efter 6 månader har du ett skelett som skyddar mot regressioner.

När är det mer lönsamt att inte röra legacy?

Om systemet är stabilt, inte kräver frekventa ändringar och inte påverkar utvecklingshastigheten för andra moduler — låt det vara. „If it ain’t broken, don’t fix it” — ett förnuftigt tillvägagångssätt för isolerade legacy-moduler med låg ändringsfrekvens. Rör kod endast när affärsförändringar behövs.

Hur uppdaterar man beroenden i ett legacy-projekt?

Använd semantisk versionshantering och uppdatera i steg: patch → minor → major. Skriv kompatibilitetstester för varje bibliotek. Dependabot eller Renovate automatiserar skapandet av PR för uppdateringar. Om ett bibliotek är deprecated — planera ersättning via abstraktion.

Vad är skillnaden mellan legacy och teknisk skuld?

Teknisk skuld — en metafor för att uppskatta kostnaden för uppskjutna förbättringar. Legacy — ett konkret system eller kod som redan är föråldrat. Teknisk skuld kan ackumuleras på en månad, legacy tar tid. Inte varje teknisk skuld blir legacy, men varje legacy innehåller teknisk skuld.

Sammanfattning

  • Legacy — kod utan tester, oavsett ålder. Färsk kod utan täckning — legacy från dag ett
  • Kodens ålder — är inte problemet. Problemet är tät koppling, brist på tester och dokumentation
  • Karaktäriseringstester — första steget före varje ändring av en legacy-modul för att fånga beteende
  • Strangler Fig-mönstret — säker migreringsstrategi med gradvis ersättning av moduler
  • Sprout method — teknik för att lägga till ny kod bredvid gammal kod utan risk att bryta
  • 35% av fullständiga omskrivningar misslyckas — stegvis migrering är säkrare än Big Rewrite
  • Isolerad legacy med låg ändringsfrekvens är bäst att låta vara

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också