Herschrijven of refactoren? Hoe je de juiste keuze maakt voor je legacy software
Je ontwikkelteam zegt het al maanden. Misschien hebben ze het ronduit uitgesproken: "We moeten dit hele systeem opnieuw bouwen." De codebase is oud, lastig te onderhouden, en elke nieuwe feature voelt als een chirurgische ingreep. Er gaat meer tijd naar het bestrijden van de code dan naar het bouwen erop.
Dan begint het idee van een schone lei te lokken. Nieuwe architectuur, moderne frameworks, best practices vanaf dag één. Het klinkt als de voor de hand liggende oplossing. Maar hier zit het probleem: rewrites zijn een van de riskantste gokken die een softwarebedrijf kan nemen. En toch is het soms de enige uitweg.
Hoe maak je dat onderscheid?
De verleiding van de grote rewrite
Het is begrijpelijk waarom rewrites zo aantrekkelijk zijn. Je huidige codebase sleept jaren aan opgestapelde workarounds, verouderde patronen en beslissingen mee die onder druk zijn genomen. Niemand begrijpt het systeem nog volledig. Nieuwe ontwikkelaars hebben maanden nodig om productief te worden. Elke wijziging veroorzaakt onverwachte bijeffecten.
Opnieuw beginnen voelt alsof het alles zou oplossen. Moderne tools, een schone architectuur, goede test coverage. Het team is enthousiast. Het management ziet de belofte van een systeem dat niet constant gepatcht hoeft te worden.
Maar enthousiasme is geen strategie.
Waarom rewrites vaker mislukken dan je denkt
Joel Spolsky noemde het "de slechtste strategische fout die een softwarebedrijf kan maken." Dat was in 2000, en de waarschuwing geldt nog steeds. Dit gaat er mis bij rewrites:
Je gooit kennis weg
Die rommelige codebase bevat jaren aan bugfixes, randgevallen en bedrijfslogica die niemand heeft gedocumenteerd. Elke vreemd uitziende workaround bestaat om een reden. Bij een rewrite verlies je al die opgebouwde kennis en moet je elk randgeval opnieuw ontdekken.
Planningen lopen altijd uit
Rewrites worden ingeschat op basis van wat we weten. Maar de echte complexiteit zit in wat we vergeten zijn. Teams onderschatten consequent met een factor twee of drie. Een "rewrite van zes maanden" wordt achttien maanden, en halverwege draait het bedrijf twee systemen tegelijk met dubbele onderhoudskosten.
De markt wacht niet
Tijdens een rewrite moet het oude systeem blijven draaien. Nieuwe features moeten nog steeds worden geleverd. Het team is verdeeld over twee systemen. Concurrenten die kozen voor refactoren leveren ondertussen features terwijl jij nog bezig bent met herbouwen wat je al had.
Het tweede-systeem syndroom
Fred Brooks beschreef het al decennia geleden: de tweede versie van een systeem wordt bijna altijd over-engineered. Het team voegt elke feature toe die ze in de eerste versie hadden gewild, bouwt uitgebreide abstracties "voor de toekomst," en creëert iets dat complexer is dan wat ze vervingen.
Wanneer refactoren de betere weg is
Refactoren betekent je bestaande code stapsgewijs verbeteren, zonder de featureontwikkeling stil te leggen. Het is minder spectaculair dan een rewrite, maar ook veel minder risicovol. Refactoren werkt goed wanneer:
- De kernarchitectuur solide is, ook al is de codekwaliteit matig
- Het systeem nog doet wat het bedrijf nodig heeft, alleen niet elegant
- Je specifieke probleemgebieden kunt aanwijzen in plaats van een totale mislukking
- Je team het systeem goed genoeg begrijpt om het veilig te verbeteren
- Je je geen maandenlange bevriezing van featureontwikkeling kunt veroorloven
- Er is een redelijke test coverage die je een vangnet geeft bij het doorvoeren van wijzigingen
Het Strangler Fig-patroon is bijzonder effectief: je bouwt nieuwe functionaliteit naast het oude systeem en routeert geleidelijk verkeer naar de nieuwe componenten. Na verloop van tijd krimpt het oude systeem totdat het met pensioen kan. Geen big bang, geen riskante omschakeling. Gewoon gestage vooruitgang.
Wanneer een rewrite wél de juiste keuze is
Ondanks alle waarschuwingen zijn er situaties waarin refactoren simpelweg niet volstaat:
- De tech stack is dood. Als je systeem draait op technologie waarvoor geen community support, beveiligingspatches of beschikbare ontwikkelaars meer zijn, kun je er niet uit refactoren. Je moet naar iets duurzaams.
- De architectuur is fundamenteel verkeerd. Als een monolithisch systeem gedistribueerd moet worden, of als het datamodel zo kapot is dat elke feature workarounds op workarounds vereist, dan brengen stapsgewijze verbeteringen je misschien nooit waar je moet zijn.
- Niemand begrijpt het systeem nog. Als het oorspronkelijke team is vertrokken zonder documentatie en de code zo verstrengeld is dat zelfs ervaren ontwikkelaars er niet veilig aan kunnen werken, dan wordt refactoren gokken met productiegevolgen.
- De bedrijfsvereisten zijn radicaal veranderd. Soms verschuift de markt zo ingrijpend dat het huidige systeem niet kan evolueren om de nieuwe realiteit te bedienen. Een retailsysteem dat een marktplaatsplatform moet worden heeft misschien een fundamenteel andere basis nodig.
Een praktisch beslissingskader
Voordat je je vastlegt op een van beide paden, stel jezelf deze vragen:
Vijf vragen om je keuze te sturen
- Kun je nog features leveren? Zo ja, zelfs langzaam, dan is refactoren waarschijnlijk haalbaar. Als featureontwikkeling in feite is gestopt, verdient een rewrite serieuze overweging.
- Ligt het probleem bij de code of bij de architectuur? Slechte code kun je opschonen. Een gebroken architectuur vereist grotere ingrepen.
- Hebben jullie de kennis? Begrijpt je team de bedrijfsregels die in het huidige systeem zitten goed genoeg om ze opnieuw te bouwen? Zo niet, wie dan wel?
- Wat is je runway? Een rewrite betekent maanden (vaak jaren) investering voordat je rendement ziet. Kan het bedrijf dat dragen?
- Kan het in fases? Als je het werk kunt opdelen in onafhankelijke stukken, dan geeft een gefaseerde aanpak (component voor component vervangen) je de voordelen van een rewrite met de veiligheid van refactoren.
Eerst duidelijkheid, dan beslissen
De rewrite-of-refactor-vraag is een van de duurste beslissingen voor een softwareorganisatie. Maak je de verkeerde keuze, dan verspil je maanden ontwikkeltijd, brand je je team op, of eindig je slechter dan waar je begon.
Het beste wat je kunt doen vóór deze beslissing is een objectieve beoordeling van je codebase laten maken. Niet door het team dat de code heeft gebouwd en niet door het team dat wil herschrijven, maar door iemand zonder belang bij de uitkomst. Een grondige source code audit vertelt je waar je werkelijk mee te maken hebt: waar de echte problemen zitten, wat te redden valt, en waar je opnieuw moet beginnen.
Zonder die duidelijkheid neem je een beslissing van tonnen op basis van frustratie en onderbuikgevoel. Met die duidelijkheid maak je een strategische keuze onderbouwd met bewijs.