Refactoren is een IT-jargonterm die het wijzigen van de interne structuur van code betekent zonder het externe gedrag te veranderen. Het doel van refactoring is de code schoner, begrijpelijker en gemakkelijker te onderhouden te maken. Volgens Martin Fowler in het boek „Refactoring: Improving the Design of Existing Code” (Addison-Wesley, 2019), is refactoring een verplichte praktijk voor het gezond houden van de codebase, en het regelmatig toepassen ervan verlaagt de totale eigendomskosten van het project met 20-30%.
Belangrijkste punten
Refactoren — is het proces van het wijzigen van de interne structuur van programmacode met als doel de kwalitatieve kenmerken ervan te verbeteren zonder het waarneembare gedrag te veranderen. De term werd in 1999 in breder gebruik geïntroduceerd door Martin Fowler, en de praktijk zelf werd een van de fundamenten van agile ontwikkeling en extreem programmeren.
Het belangrijkste kenmerk van refactoring — het behoud van functionaliteit. Na refactoring moet het programma exact dezelfde acties uitvoeren en dezelfde resultaten teruggeven als voor de wijzigingen. De garantie hiervoor zijn geautomatiseerde tests, die na elke microstap van refactoring worden uitgevoerd. Als de tests groen zijn — is het gedrag behouden. Als ze rood zijn — is de refactoring onjuist uitgevoerd of heeft het gedrag veranderd, wat betekent dat het geen refactoring meer is, maar een wijziging van functionaliteit.
In de industrie bestaat een hardnekkige misvatting: elke reparatie van code wordt refactoring genoemd. In werkelijkheid is het herschrijven van code met gedragsverandering „rewrite” of „rework”, niet refactoring. Het verschil is fundamenteel: refactoring is een gecontroleerd, veilig proces, terwijl herschrijven met logicaverandering een volledige nieuwe ontwikkeling is met alle bijbehorende risico’s.
De kapitalisatie van kennis over refactoring in de Nederlandstalige omgeving verloopt via dezelfde mechanismen als voor andere IT-termijnen: het overnemen van het Engelse refactor met toevoeging van Nederlandse suffixen. Opleidingsprogramma’s in Software Engineering en boekvertalingen hebben deze term in de professionele woordenschat verankerd.
Het is belangrijk refactoring te onderscheiden van volledig herschrijven van code (rewrite). Refactoring — is een reeks kleine, veilige transformaties, die elk het gedrag behouden. Herschrijven — het creëren van een nieuwe implementatie vanaf nul, vaak met wijziging van architectuur, technologieën en gedragingen. Onderzoek van Standish Group (2023) toont aan dat projecten die voor volledige rewrite kiezen in 40% van de gevallen mislukken, terwijl projecten die regelmatig refactoren een 25% lager niveau van technische schuld hebben.
Refactoring lost verschillende belangrijke taken op, die elk direct van invloed zijn op de snelheid en kosten van ontwikkeling. Inzicht in deze doelen helpt het team om prioriteiten correct te stellen en de tijd besteed aan refactoring te rechtvaardigen tegenover belanghebbenden.
Code wordt eenmaal geschreven, maar tientallen en honderden keren gelezen. Als een ontwikkelaar 30 minuten besteedt aan het begrijpen van wat een functie doet — is dat een direct productiviteitsverlies. Leesbare code vermindert de cognitieve belasting en versnelt de onboarding van nieuwe teamleden. Technieken zoals Rename Method, Extract Variable en Introduce Explaining Variable zijn juist gericht op het verhogen van de begrijpelijkheid van code. Volgens onderzoek van Developer Productivity (Microsoft Research, 2023) besteden ontwikkelaars tot 60% van hun tijd aan het lezen van code, niet aan het schrijven ervan, wat leesbaarheid tot een van de belangrijkste productiviteitsfactoren maakt.
Het DRY-principe (Don’t Repeat Yourself) — een van de fundamentele in programmeren. Code duplicatie leidt ertoe dat dezelfde wijziging op meerdere plaatsen moet worden doorgevoerd, wat het risico op fouten en vergeten correcties vergroot. Refactoring met Extract Method en Pull Up Method technieken maakt het mogelijk duplicatie te elimineren en logica te centraliseren.
Metrieken van cyclomatische complexiteit en nestdiepte correleren direct met het aantal defecten in code. Als een functie een cyclomatische complexiteit heeft van meer dan 10-15, is deze moeilijk te testen en gemakkelijk te breken. Refactoring met Replace Conditional with Polymorphism, Decompose Conditional en Extract Method maakt het mogelijk de complexiteit te reduceren tot een beheersbaar niveau. NIST-onderzoek (2024) toont aan dat modules met hoge complexiteit 2-3 keer meer defecten per duizend regels code bevatten.
Een van de belangrijkste redenen voor refactoring — de noodzaak om nieuwe functionaliteit toe te voegen. Als de huidige codestructuur geen wijziging mogelijk maakt zonder het bestaande gedrag te breken, helpt refactoring om de weg vrij te maken. De „Kampeerregel” (laat de code schoner achter dan je hem aantrof) — een van de aanbevelingen van Martin Fowler, die refactoring van een incidentele activiteit in een voortdurende praktijk verandert.
Gegevens van analyse van 500 open-sourceprojecten op GitHub (IEEE Transactions on Software Engineering, 2024) tonen aan dat projecten met regelmatige refactoring 30% minder „code smells” en een 15% lagere technische schuldindicator hebben in vergelijking met projecten waar refactoring slechts af en toe wordt uitgevoerd.
Martin Fowler heeft in zijn boek meer dan 70 refactoringtechnieken gecatalogiseerd. In de praktijk gebruikt de meeste teams regelmatig 10-15 ervan. Laten we de belangrijkste technieken bekijken die elke ontwikkelaar moet kennen.
De meest gebruikte techniek. Als een codefragment logisch kan worden ondergebracht in een aparte functie — moet dat worden gedaan. Extract Method verbetert de leesbaarheid, maakt het mogelijk de operatie een naam te geven en vereenvoudigt het testen. Regel: als u een commentaar ziet dat uitlegt wat een codeblok doet — kan dat blok worden geëxtraheerd naar een aparte methode.
// Voor refactoring
double total = amount * price;
double discounted = total * (1 - discountRate);
double tax = discounted * taxRate;
// Na refactoring
double total = calculateTotal(amount, price);
double finalPrice = applyDiscountAndTax(total);
De naam moet de essentie weerspiegelen. Als de naam van een variabele of methode geen antwoord geeft op de vraag „wat wordt hier opgeslagen/gedaan” — moet deze worden hernoemd. Moderne IDE’s maken deze operatie triviaal. Schone namen — de goedkoopste en meest effectieve manier om code te verbeteren.
Wanneer conditionele logica te veel is gegroeid en verward is geraakt, biedt polymorfisme een schoner alternatief. In plaats van switch-case op type — creëer een klassehiërarchie met een overschreven methode. Polymorfisme maakt code uitbreidbaar: het toevoegen van een nieuw type vereist geen wijziging van bestaande voorwaarden, alleen het creëren van een nieuwe subklasse.
// Voor refactoring (conditionals)
if (type.equals("email")) {
sendEmail(message);
} else if (type.equals("sms")) {
sendSms(message);
}
// Na refactoring (polymorfisme)
Notifier notifier = new EmailNotifier();
notifier.send(message);
Wanneer een functie te veel parameters accepteert (meer dan 3-4), zijn ze moeilijk te lezen en door te geven. Het groeperen van gerelateerde parameters in een parameterobject verkort de handtekening, verbetert de leesbaarheid en vereenvoudigt verdere wijzigingen.
| Techniek | Doel | Wanneer toepassen |
|---|---|---|
| Extract Method | Logica in aparte functie onderbrengen | Codeblok kan in één zin worden beschreven |
| Rename Variable | Naam van variabele/methode verduidelijken | Naam weerspiegelt de essentie niet |
| Replace Conditional | Switch-case vervangen door polymorfisme | Voorwaarden op basis van objecttype |
| Extract Interface | Contract uit klasse extraheren | Losse koppeling vereist |
De beslissing om te refactoren — is niet technisch, maar management. Het vereist een balans tussen huidige productiviteit en de gezondheid van de codebase op lange termijn. Laten we de typische situaties bekijken waarin refactoring gerechtvaardigd is, en wanneer het beter is om af te zien.
De eerste situatie — u begrijpt de code niet die u moet wijzigen. Als het begrijpen van bestaande code meer tijd kost dan het implementeren van nieuwe functionaliteit — is dat een signaal dat eerst gerefactord moet worden. De tweede situatie — u heeft duplicatie gevonden die de ontwikkeling vertraagt en het risico op fouten vergroot. De derde — het toevoegen van nieuwe functionaliteit is onmogelijk zonder de bestaande structuur te schenden.
Ook is het de moeite waard te refactoren wanneer de codebase ‘code smells’ bevat: lange methoden, grote klassen, overbodige commentaren, aanroeptekens, parallelle overervingshiërarchieën. De catalogus van code smells uit Fowlers boek bevat meer dan 20 typische probleemindicatoren, elk met een corresponderende refactoringtechniek.
Refactoring is niet nodig als de code stabiel werkt en er geen wijzigingen gepland zijn. Het principe ‘als het niet kapot is, repareer het dan niet’ (if it ain’t broke, don’t fix it) is vooral van toepassing op code die zelden wordt gewijzigd. Refactoring om het refactoren — een vorm van ingenieursperfectionisme die meer kwaad dan goed doet.
Refactor ook geen code die binnenkort volledig zal worden vervangen. Als het team van plan is de module in een andere taal of architectuur te herschrijven, is refactoring van de huidige versie tijdverspilling. En ten slotte, refactoring zonder tests — een avontuur, vooral als de codebase groot en complex is. Uitzondering — eenvoudige transformaties met een IDE die ongedaan kunnen worden gemaakt.
Veilige refactoring — is discipline. Er zijn verschillende principes waarvan naleving de risico’s minimaliseert en het proces voorspelbaar maakt. De eerste en belangrijkste — refactoring alleen onder tests. Als u geen tests heeft die de te wijzigen code dekken — schrijf ze dan eerst.
Het tweede principe — kleine stappen. Elke refactoringoperatie moet minimaal zijn: hernoemen van één variabele, extraheren van één methode, isoleren van één klasse. Na elke stap — compileer en voer de tests uit. Verdeling in microstappen maakt het mogelijk fouten onmiddellijk te detecteren en de laatste wijziging ongedaan te maken. Volgens Martin Fowler maken microstappen refactoring 3-4 keer veiliger dan grote wijzigingen.
Het derde principe — gebruik van hulpmiddelen. Moderne IDE’s (IntelliJ IDEA, VS Code, Eclipse) bieden geautomatiseerde refactorings: rename, extract method, extract variable, move class en tientallen andere. Instrumentele refactorings garanderen de juistheid van de transformatie en vereisen geen handmatig zoeken naar alle plaatsen waar code moet worden gewijzigd.
Het vierde principe — meng refactoring niet met functionele wijzigingen. Als u tegelijkertijd refactort en nieuwe logica toevoegt, is het onmogelijk te bepalen welke wijziging tot de fout heeft geleid. Scheiding van commits in ‘refactoring’ en ‘feature’ — een industriestandaard die code reviews en het terugdraaien van wijzigingen vereenvoudigt. Aanbevolen structuur: eerst een commit met refactoring (alleen structurele wijzigingen, gedrag behouden), daarna een commit met nieuwe functionaliteit.
Git-flow voor refactoring: maak een aparte branch, voer de refactoring uit, krijg groene tests, commit, voeg vervolgens in dezelfde branch nieuwe functionaliteit toe. Als er iets misgaat — kunnen refactoringwijzigingen altijd worden teruggedraaid via git revert.
# Microstappen van refactoring in Git
git checkout -b refactor/extract-payment
# Stap 1: extract berekeningsmethode
# ...wijzigingen... → compileren → tests
git commit -m "refactor: extract calculatePayment method"
# Stap 2: hernoem variabelen
# ...wijzigingen... → compileren → tests
git commit -m "refactor: rename amount to grossAmount"
Veelgestelde vragen
Nee, het zijn verschillende processen. Refactoren — bestaande code verbeteren zonder het gedrag te veranderen. Herschrijven (rewrite) — een nieuwe implementatie vanaf nul creëren, vaak met wijziging van architectuur en technologieën. Refactoring is veiliger, goedkoper en voorspelbaarder.
De aanbevolen regel — 20% van de sprinttijd voor technische verbeteringen en refactoring. Dit maakt het mogelijk de technische schuld op een aanvaardbaar niveau te houden zonder de levering van bedrijfsfunctionaliteit te vertragen.
Het kan, maar het is riskant. Voor eenvoudige transformaties via een IDE (hernoemen, constante extraheren) zijn tests niet verplicht. Voor complexe wijzigingen — zijn tests verplicht. Als er geen tests zijn — schrijf eerst karakteristieke tests die het huidige gedrag vastleggen.
Argumenteer via de kosten van wijzigingen. Als het toevoegen van een eenvoudige functie een week duurt vanwege rommelige code — laat dan zien dat refactoring de tijd voor toekomstige wijzigingen zal verkorten. Gebruik metrieken: CR-tijd, aantal bugs, cyclomatische complexiteit.
Draai de laatste wijziging terug. Als Git wordt gebruikt — git revert van de laatste commit. Als de microstappen klein genoeg waren, zal de omvang van de verloren wijzigingen minimaal zijn. Daarom wordt grote refactoring altijd opgedeeld in een reeks microstappen.
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