Legacy — is niet zomaar oude code. Het is een werkend systeem dat geld oplevert voor het bedrijf, maar de ontwikkeling vertraagt. In mobiele appontwikkeling kan legacy geschreven zijn in Objective-C, verouderde bibliotheken of architectuurpatronen gebruiken. Volgens het rapport van CAST Software (2024) is de gemiddelde leeftijd van een coderegel in enterprise-projecten meer dan 14 jaar. De strategie voor het werken met legacy bepaalt of het een rem wordt of een beheersbaar actief blijft.
Belangrijkste punten
Legacy — code of een systeem dat nog in productie werkt, maar niet meer voldoet aan moderne kwaliteitsstandaarden. Legacy kan geschreven zijn in een verouderde taal (bijv. Objective-C in plaats van Swift), gebruikmaken van niet-ondersteunde bibliotheken of architectuurpatronen die al lang als antipatronen worden beschouwd.
Het belangrijkste kenmerk van legacy is het ontbreken van tests. Volgens de definitie van Michael Feathers (2004) is legacy code code zonder tests. Als het gedrag niet veilig kan worden gewijzigd, heeft het systeem de status legacy, ongeacht de leeftijd. Nieuwe code zonder unittesten — is legacy vanaf dag één.
Legacy is niet per se slecht. Een goed ontworpen systeem in Java 8 kan betrouwbaarder en begrijpelijker zijn dan chaotische code in Kotlin met coroutines. Codeleeftijd is geen kwaliteitsindicator — het belangrijkste is in hoeverre het systeem vatbaar is voor wijzigingen en uitbreiding.
Elk succesvol systeem wordt na verloop van tijd legacy. Dit is een natuurlijk proces: technologieën ontwikkelen zich sneller dan code kan worden herschreven. Een app die 5 jaar geleden in Swift 2 is geschreven, is vandaag legacy, hoewel hij op het moment van creatie modern was.
De bedrijfswaarde van legacy wordt vaak onderschat. Het systeem werkt stabiel, verwerkt transacties, slaat gegevens op — herschrijven brengt risico's met zich mee. Volgens Standish Group (2024) mislukt 35% van de volledige herschrijfprojecten. Economisch gezien is het niet gerechtvaardigd om van legacy af te komen, maar om ermee te leren werken.
De beste strategieën — stapsgewijze migratie, inkapseling van oude code achter nieuwe interfaces en geautomatiseerd testen. Legacy wordt alleen een probleem wanneer het niet meer vatbaar is voor wijzigingen met voorspelbare kosten.
Ontbreken van geautomatiseerde tests — de belangrijkste indicator. Als een ontwikkelaar na het wijzigen van één coderegel de tests niet kan uitvoeren en controleren of er niets kapot is — hebt u te maken met legacy. Aanvullend kenmerk: de implementatieprocedure duurt uren en vereist handmatige handelingen.
Documentatie komt niet overeen met de code — nog een kenmerk. Architectuurdiagrammen zijn verouderd, opmerkingen beschrijven gedrag dat al is veranderd. Time-to-ramp-up voor een nieuwe ontwikkelaar duurt langer dan een maand — een teken van hoge complexiteit en lage onderhoudbaarheid van het systeem.
Aanvullende kenmerken: monolithische architectuur zonder duidelijke grenzen, handmatig testen als belangrijkste verificatiemethode, lange CI-pipeline (meer dan 30 minuten), gebruik van bibliotheken zonder actuele versies en onmogelijkheid om afhankelijkheden te updaten zonder naburige modules te breken.
Het fenomeen „breekbare code” — een wijziging op één plek breekt drie andere. Dit is een gevolg van sterke koppeling (tight coupling), waarbij modules te veel van elkaar weten. Hoe hoger de coupling, hoe sneller het systeem overgaat naar de categorie legacy.
Vermindering van snelheid — het belangrijkste risico. Het toevoegen van een eenvoudige functie vereist uren codebestudering en dagen testen. Volgens Stripe (2024) besteden ontwikkelaars 33% van hun tijd aan het overwinnen van technische schuld, die direct verband houdt met de aanwezigheid van legacy-modules in het project.
Verlies van expertise — de auteurs van de originele code verlaten het bedrijf en de documentatie is onvolledig. Nieuwe ontwikkelaars zijn bang om onbegrijpelijke modules aan te raken, wat leidt tot het effect van „bevroren code”: de module ontwikkelt zich niet, maar blijft wel werken. De Bus factor van dergelijke systemen is kritisch laag.
Beveiliging — verouderde bibliotheken bevatten bekende kwetsbaarheden. Het gebruik van OpenSSL 1.0.2 of verouderde versies van Jackson in Java-projecten is een directe weg naar beveiligingsincidenten die het bedrijf reputatie en klanten kunnen kosten.
Demotivatie van het team — werken met legacy zonder een strategie voor verbetering vermindert de tevredenheid van ontwikkelaars. Het team is niet langer trots op het product, het personeelsverloop neemt toe, wat de systeemontwikkeling nog verder vertraagt.
Karakterisatietests — de eerste stap vóór elke wijziging van legacy-code. Voer de code uit op bekende invoergegevens en leg de verwachte uitvoer vast. Deze tests leggen het huidige gedrag vast als specificatie. Golden master testing — een variant waarbij de uitvoergegevens worden vergeleken met een referentiebestand.
Seam-analyse — het zoeken naar punten waar de koppeling kan worden verbroken zonder gedragsverandering. Michael Feathers onderscheidt verschillende soorten seams: preprocessor seam, object seam, link seam. Object seam — de meest voorkomende: vervanging van een echt object door een teststub via een interface.
Sprout method en Sprout class — technieken om nieuwe code naast oude code toe te voegen, niet erin. In plaats van een bestaande methode te wijzigen, maak je een nieuwe methode met de gewenste logica en roep je deze aan vanuit de oude. Dit minimaliseert het risico dat werkende code kapot gaat.
class LegacyPaymentProcessor {
def process(payment) {
// 200 regels legacy-code die niet aangeraakt mogen worden
logPayment(payment) // sprout method
}
def logPayment(payment) {
// nieuwe code toegevoegd naast legacy
}
}
Strangler Fig-patroon — de aanbevolen aanpak voor legacymigratie. De nieuwe module wordt parallel gemaakt, het verkeer wordt geleidelijk van oud naar nieuw geschakeld. De oude module „sterft” vanzelf wanneer hij geen verzoeken meer ontvangt. Het patroon minimaliseert risico's en maakt terugdraaien bij problemen mogelijk.
Branch by Abstraction — een techniek waarbij een abstractie wordt gecreëerd over de oude en nieuwe implementatie. De clientcode schakelt over naar de abstractie, de oude implementatie wordt geleidelijk vervangen door de nieuwe. Voorbeeld: vervanging van de netwerklaag van AFNetworking naar Alamofire via een uniform protocol NetworkService.
Stapsgewijze migratie — het opsplitsen van de overgang in kleine stappen: inkapseling van de oude module → schrijven van tests → maken van de nieuwe module → parallelle uitvoering → verwijderen van de oude module. Elke stap eindigt met een stabiele systeemstatus, waardoor wijzigingen op elk moment kunnen worden geïmplementeerd.
Veelgestelde vragen
Volledig herschrijven is de meest risicovolle optie. Slechts 25% van de projecten Big Rewrite wordt op tijd succesvol afgerond. Pas liever het Strangler Fig-patroon toe: vervang modules stapsgewijs zonder het product te stoppen. Elke iteratie levert bedrijfswaarde op en de risico's worden over de tijd verdeeld.
Begin met karakterisatietests: voer de module uit op bekende gegevens, leg het resultaat vast. Golden master testing — een eenvoudige manier om gedrag vast te leggen. Voeg elke keer tests toe wanneer je een coderegel aanraakt. Na 6 maanden heb je een raamwerk dat beschermt tegen regressies.
Als het systeem stabiel is, geen frequente wijzigingen vereist en de ontwikkelsnelheid van andere modules niet beïnvloedt — laat het met rust. „If it ain’t broken, don’t fix it” — een verstandige benadering voor geïsoleerde legacy-modules met een lage wijzigingsfrequentie. Raak code alleen aan wanneer er zakelijke wijzigingen nodig zijn.
Gebruik semantic versioning en werk in stappen bij: patch → minor → major. Schrijf voor elke bibliotheek compatibiliteitstests. Dependabot of Renovate automatiseren het maken van PR's voor updates. Als een bibliotheek deprecated is — plan vervanging via een abstractie.
Technische schuld — een metafoor voor het inschatten van de kosten van uitgestelde verbeteringen. Legacy — een concreet systeem of code die al verouderd is. Technische schuld kan in een maand worden opgebouwd, legacy kost tijd. Niet elke technische schuld wordt legacy, maar elke legacy bevat technische schuld.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook