Cyclomatische complexiteit: wat bouwen of refactoren
Samenvatting
Cyclomatische complexiteit is een metriek uit 1976 die onafhankelijke uitvoeringspaden door een functie telt. Scores boven 10 vereisen tests; boven 20 refactor je voor je iets nieuws toevoegt; boven 50 herschrijf je. Als beslissingskaart gebruikt geeft het je een prioriteitswachtrij: de hoog-CC-functies die je volgende feature raakt zijn je echte sprintplan. Dit artikel laat zien hoe je de scan uitvoert, de resultaten leest, en complexiteitsdata omzet in een shipping-beslissing.
Cyclomatische complexiteit: wat bouwen of refactoren
Cyclomatische complexiteit (CC) is de metriek die elke functie in je codebase een risicoscore geeft. Functies boven CC 10 hebben tests nodig voor je ze aanraakt. Boven CC 20 refactor je eerst voor je iets nieuws toevoegt. Boven CC 50 herschrijf je. Dat is de beslissingsboom. Dit artikel legt uit hoe je vandaag nog een scan uitvoert op je project en de output omzet in een sprintplan.
Je opent de codebase om 22:00. Je weet welke feature je wilt shippen. Twintig minuten later debug je iets wat er niets mee te maken heeft. De functie die je bewerkt is 300 regels lang, handelt zes verschillende gevallen af, en niemand -- inclusief jijzelf -- weet meer waarom het zo groot is geworden.
Dit is geen planningsprobleem. Het is een meetprobleem. Je had geen tool die vroeg waarschuwde. Cyclomatische complexiteit had dat kunnen zijn, en het had je die debug-sessie bespaard.
Wat cyclomatische complexiteit precies meet
Thomas McCabe publiceerde de metriek in 1976. De formule is M = E - N + 2P, waarbij E de kanten zijn, N de knopen, en P de verbonden componenten in de controlestroom-graaf van een functie. In de praktijk: begin bij 1, voeg 1 toe voor elke if, else if, for, while, case, catch, &&, of ||. Dat is de score.
Een functie zonder vertakking heeft CC = 1. Een functie die tien condities controleert, over een lijst itereert, en drie soorten fouten afhandelt, zit rond CC 15-20. Een functie die door zes devs is opgebouwd met patches over twee jaar kan CC 60 bereiken.
De metriek meet niet alles. Ze meet geen nestdiepte, naamkwaliteit of abstractieduidelijkheid. Een functie kan lage CC hebben en toch moeilijk leesbaar zijn. Maar een functie met CC boven 25 is bijna altijd moeilijk leesbaar. De correlatie in die richting is consistent genoeg om als prioriteitsfilter te dienen.
De drempelwaarden die je volgende stap bepalen
De meeste stijlgidsen en statische analysetools komen overeen in vergelijkbare bereiken:
CC 1-10 (Acceptabel): shippen maar
CC 11-20 (Aandacht nodig): voeg tests toe voor je het aanpast
CC 21-50 (Hoog risico): refactor voor je features toevoegt
CC >50 (Niet te testen): herschrijven, niet patchen
De originele aanbeveling van NIST was een plafond van 10 per functie. In de praktijk behandelen de meeste engineers 15 als een realistische zachte grens voor productiecode, en alles boven 20 als een blokkade voor nieuw werk dat die functie raakt.
De tabel is je beslissingsboom voor wat je als volgende bouwt. Als je backlog vol is en je niet kunt beslissen of je een feature toevoegt of een bestaande module repareert, voer dan eerst een complexiteitsscan uit. De functies boven 20 zijn je verplichte stop voor alles nieuws ze aanraakt.

Je eerste scan in 5 minuten uitvoeren
Elk groot taal-ecosysteem heeft een CLI-tool klaarstaan. Je hebt voor deze eerste stap geen SaaS-dashboard nodig.
Python (Radon):
pip install radon
radon cc -s -a ./srcJavaScript / TypeScript (ESLint):
{
"rules": { "complexity": ["error", 10] }
}Voer daarna eslint ./src --ext .ts,.js uit in je pipeline.
Go (gocyclo):
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
gocyclo -over 10 ./...Java / Kotlin (PMD):
pmd check -d ./src -R rulesets/java/quickstart.xml | grep CyclomaticComplexityDe output geeft elke functie gesorteerd op CC-score. Wat je zoekt: de 10 functies met de hoogste score in je project. Sla die lijst op. Dat is je prioriteitswachtrij voor de volgende sprint.
Het rapport lezen als een beslissingskaart
Functies met hoge CC clusteren op voorspelbare plekken. In een aanbevelings-API van ongeveer 8.000 regels surfacete radon cc -s drie functies met CC boven 30. Die drie zaten allemaal in de data-normalisatielaag. Die laag was incrementeel gepatcht over zes maanden, elke keer voor een ander randgeval van een databron. Niemand had ooit naar de cumulatieve schade gekeken.
Elke nieuwe feature die de normalisatielaag raakte, duurde 40% langer om te shippen. Er werd twee dagen besteed, voor de volgende sprint, aan het refactoren van die drie functies: CC-scores van 32, 28 en 31 naar 7, 5 en 8 gebracht. De volgende sprint was de snelste in vier maanden. Drie functies. Twee dagen. Vier maanden vertraging, verklaard.
Het patroon is consistent in codebases: ongeveer 10-15% van de functies bevatten 70-80% van de complexiteit in elk organisch gegroeid project. Die concentratie is je echte roadmap.
Voor side projects specifiek telt dit zwaarder dan in teaminstellingen. Je kunt een rommelige functie niet aan een collega doorgeven. De volledige cognitieve kosten van het herbeginnen bij CC 30-code vallen op jou, meestal om 22:00, zes maanden nadat je het hebt geschreven.
Het tweede ding dat complexiteitsrapporten goed doen: ze geven je een concreet antwoord als je verlamd bent tussen "een feature toevoegen" en "eerst opruimen". De scan verwijdert de ambiguïteit. Als de feature hoog-CC-code raakt, ruim je eerst op. Als niet, ship je. Dat is een beslissing, geen discussie.
Dat klinkt simpel, maar het elimineert weken van verborgen technische schuld die je pas ontdekt als je er middenin zit. De complexiteitsscan maakt het onzichtbare zichtbaar voor je begint. En dat levert je iets op wat waardevoller is dan schone code: voorspelbare velocity.
Wanneer hoge complexiteit de juiste keuze is
Niet elke hoog-CC-functie is een probleem. Een betaalstatus-machine die 12 transactiestatussen afhandelt, moet echt 12 statussen afhandelen. Een parser die 15 grammaticaregels verwerkt, heeft 15 echte gevallen. Die platslaan naar 15 helperfuncties met CC 1 elk reduceert de complexiteit niet -- het verspreidt het over bestanden die nu moeilijker samen te navigeren zijn.
De nuttige vraag is niet "is dit CC te hoog?" maar "is dit CC hoger dan het domein vereist?" Een routeringsfunctie die 15 URL-patronen afhandelt met CC = 18 is waarschijnlijk passend. Een gebruikersprofiel-update-functie met CC = 18 die groeide door geaccumuleerde patches voor randgevallen die niemand had gepland, is een ander probleem.
Houd CC onder 15 op je kritieke paden. Laat het hoger lopen in echt complexe domeinen, en documenteer de reden inline. De functies die je later verrassen zijn altijd de functies zonder rechtvaardiging voor hun complexiteit dan geaccumuleerde fixes.
Een nuttige gewoonte: voeg een commentaarregel toe wanneer je bewust een functie boven CC 15 laat. Schrijf wat het domein vereist en waarom splitsen hier geen voordeel geeft. Zes maanden later bedank je jezelf.

Complexiteitschecks toevoegen aan je CI
De scan eenmalig handmatig uitvoeren is nuttig. Er een haak van maken in CI is wat het gedrag over tijd echt verandert. De praktische opstelling: stel een drempelwaarde in je linterconfiguratie in, laat de build mislukken als een nieuwe functie die overschrijdt, en sla het complexiteitsrapport op als CI-artefact bij elke run. De lijst bestaat bij elke build, zonder dat iemand eraan hoeft te denken het te genereren.
Voor GitHub Actions met een Python-project:
- name: Complexiteitscheck
run: |
pip install radon
radon cc -n C -s ./src
if [ $? -ne 0 ]; then exit 1; fiVoor JavaScript met ESLint al in de pipeline, voeg "complexity": ["error", 12] toe aan je regels. Elke PR die een functie boven 12 pusht, mislukt automatisch.
Een praktische teamstandaard: CC <= 15 als harde CI-blokkade, CC 11-15 als waarschuwing die een inline commentaar vereist met de zakelijke reden. Die tweede laag dwingt het gesprek af zonder elke codereview een onderhandeling over drempelwaardeuitzonderingen te maken.
Drie tools voor continue tracking
De bovenstaande CLI-tools geven je een eenmalige snapshot. Voor continue zichtbaarheid op projectniveau steken drie tools eruit.
SonarQube is de meest complete optie voor projectbrede complexiteitsregistratie. De community-editie dekt cyclomatische complexiteit, cognitieve complexiteit en testdekking in één dashboard. Quality gates kunnen een merge blokkeren als nieuwe code de complexiteit boven een drempelwaarde pusht. Dit is de tool om als eerste naar te grijpen als een project meer dan twee bijdragers heeft en een echt reviewproces.
CodeScene koppelt complexiteitsscores aan commit-geschiedenis en brengt functies aan de oppervlakte die zowel complex zijn als vaak worden gewijzigd. Die intersecties zijn je echte technische schuld -- niet alleen moeilijk te begrijpen, maar actief tijdkosten bij elke sprint. Als je een argument moet maken voor een refactoring-sprint op de roadmap van een team, is de output van CodeScene het argument.
Code Climate Quality is de lichtere optie, geschikt voor solo-projecten en open-source repos. GitHub-integratie werkt out of the box, de standaarden zijn verstandig, en de gratis laag voor publieke repos is bruikbaar. Als je een side project beheert en complexiteitsdrift wilt bijhouden zonder infrastructuur op te zetten, begin hier. Je koppelt je repo, en elke PR krijgt automatisch een complexiteitsrapport. Geen deployment, geen onderhoud, geen maandelijkse factuur voor een team van een.
Wat de metriek je werkelijk dwingt te beslissen
Cyclomatische complexiteit zegt je niet of je code goed is. Het zegt je waar het risico is geconcentreerd. Dat is een nuttiger stuk informatie.
Voer de scan uit op je huidige project voor je volgende sprint. Kijk naar de top 10 functies op score. Vraag welke je volgende feature aanraakt. Als het antwoord "drie ervan, allemaal boven CC 20" is, is je sprintplan duidelijk: breng die drie functies onder CC 10, ship dan de feature. Het zal de helft van de tijd kosten die het anders zou hebben gekost.
Voor builders: als je op zoek bent naar je volgende side project en je werkt in echte codebases, is je complexiteitsrapport een spec. De meest complexe module die de velocity blokkeert -- een die complex is en voortdurend wordt aangeraakt -- is een tool die de moeite waard is om rond te bouwen. Een lichtgewicht complexiteitsdashboard dat CC-scores correleert met git blame-data en frequentie van gewijzigde bestanden, geprijsd voor een team van twee in plaats van een enterprise-contract, is een project dat nog niet volledig bestaat. De tooling-gap is echt.