It ‘ s no secret code is een ingewikkeld iets om te schrijven, debuggen en onderhouden wat nodig is voor een hoge softwarekwaliteit. Bovendien brengt hoge code complexiteit een hoger niveau van code defecten met zich mee, waardoor de code duurder is om te onderhouden.
dus, door de complexiteit van de code te verminderen, kunnen we het aantal bugs en defecten verminderen, samen met de levensduurkosten. Wat is complexe code precies? Hoe kunnen we objectief beoordelen hoe complex een stuk code is, of dat een volledige codebase is of een kleine functie?
In dit artikel, ga ik door drie complexe metrics lopen voor het beoordelen van code complexiteit. Deze zijn:
- Cyclomatische complexiteit
- switch statement and logic condition complexity
- Developer skill
Ik zal ook enkele van de voordelen doornemen van het beoordelen en begrijpen van code complexiteit.
- Cyclomatische complexiteit
- voorbeeld één
- voorbeeld twee
- voorbeeld drie
- complexiteit van switch Statement en logica Condition
- vaardigheidsniveau softwareontwikkelaar
- de voordelen van het meten van Softwarecomplexiteit
- betere Tests
- verminderd risico
- lagere kosten
- grotere voorspelbaarheid
- helpt ontwikkelaars te leren
- dat is een Wrap
Cyclomatische complexiteit
in 1976 stelde Thomas McCabe Snr een metriek voor voor de berekening van de complexiteit van de code, genaamd Cyclomatische complexiteit. Het wordt gedefinieerd als:
een kwantitatieve maat voor het aantal lineair onafhankelijke paden door de broncode van een programma … berekend met behulp van de regelstroomgrafiek van het programma.
als u niet bekend bent met een Regelstroomgrafiek:
het is een weergave, met behulp van grafieknotatie, van alle paden die door een programma kunnen worden doorkruist tijdens de uitvoering ervan.
zei duidelijker: hoe minder paden door een stuk code en hoe minder complex deze paden zijn, hoe lager de Cyclomatische complexiteit. Hierdoor is de code minder ingewikkeld. Om de metriek aan te tonen, laten we drie, enigszins willekeurige, Go code voorbeelden gebruiken.
voorbeeld één
func main() { fmt.Println("1 + 1 =", 1+1)}
omdat er maar één pad door de functie is, heeft het een Cyclomatische Complexiteitsscore van 1, die we kunnen vinden door gocyclo erop te draaien.
voorbeeld twee
func main() { year, month, day := time.Now().Date() if month == time.November && day == 10 && year == 2018 { fmt.Println("Happy Go day!") } else { fmt.Println("The current month is", month) }}
in dit voorbeeld wordt het huidige jaar, de maand en de dag opgehaald. Met deze informatie controleren we vervolgens of de huidige datum 10 November 2018 is met een if/else voorwaarde.
als dat zo is, drukt de code ” Happy Go day!”naar de console. Als het niet, dan drukt het “de huidige maand is” en de naam van de huidige maand. Het voorbeeld van de code wordt ingewikkelder gemaakt als de voorwaarde bestaat uit drie subvoorwaarden. Gezien dat, het heeft een hogere complexiteit score van 4.
voorbeeld drie
func main() { _, month, _ := time.Now().Date() switch month { case time.January: fmt.Println("The current month is January.") case time.February: fmt.Println("The current month is February.") case time.March: fmt.Println("The current month is March.") case time.April: fmt.Println("The current month is April.") case time.May: fmt.Println("The current month is May.") default: fmt.Println("The current month is unknown.") }}
in dit voorbeeld printen we de huidige maand af, gebaseerd op de waarde van month
, opgehaald uit de aanroep naar time.Now().Date()
. Er zijn zeven paden door de functie, één voor elk van de case statements en één voor de standaard.
hierdoor is de Cyclomatische complexiteit 7. Als we rekening hadden gehouden met alle maanden van het jaar, samen met een default, zou zijn score echter veertien zijn. Dat gebeurt omdat Gocyclo de volgende berekeningsregels gebruikt:
1 is de basiscomplexiteit van een functie
+1 voor elk “als”, “voor”, “geval’, ‘&&’ of ‘||’
met behulp van deze drie voorbeelden kunnen we zien dat door het hebben van een standaard metriek voor het berekenen van code complexiteit, we snel kunnen beoordelen hoe complex een stuk code is.
We kunnen ook zien hoe verschillende complexe secties van code zijn in vergelijking met elkaar. Cyclomatische complexiteit is echter niet genoeg op zichzelf.
complexiteit van switch Statement en logica Condition
de volgende beoordelaar van complexiteit van code is de complexiteit van switch statement en logica condition. In de code voorbeeld hieronder, Ik heb de tweede Ga voorbeeld genomen en splits de verbinding als voorwaarde in drie geneste voorwaarden; een voor elk van de oorspronkelijke voorwaarden.
func main() { year, month, day := time.Now().Date() output := fmt.Sprintf("The current month is %s", month) if month == time.November { if day == 13 { if year == 2018 { output = fmt.Sprintf("Happy Go day!") } } } fmt.Println(output)}
Wat is gemakkelijker te begrijpen (of minder ingewikkeld), de oorspronkelijke, of deze? Laten we hier nu op voortbouwen, door de volgende drie vragen te overwegen.
- wat als we, zoals hierboven, meerdere if-voorwaarden hadden en elk ervan vrij complex was?
- wat als we meerdere if-condities hadden en de code in de body van elk ervan vrij complex was?
- zou de code gemakkelijker of moeilijker te begrijpen zijn?
eerlijk gezegd is het zo dat hoe groter het aantal geneste Voorwaarden en hoe hoger het niveau van complexiteit binnen deze voorwaarden, hoe hoger de complexiteit van de code.
vaardigheidsniveau softwareontwikkelaar
hoe zit het met het vaardigheidsniveau van de ontwikkelaar? Neem een kijkje op de C versie van de tweede Ga voorbeeld hieronder.
#include <stdio.h>#include <time.h>#include <string.h>int main(){ time_t t = time(NULL); struct tm tm = *localtime(&t); const char * months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; if (tm.tm_year == 2018 && strncmp(months, "November", strlen(months)) == 0 && tm.tm_mday == 10) { printf("Happy C Day!.\n"); } else { printf("The current month is %s.\n", months); }}
technisch gezien doet het wat de andere voorbeelden doen. Er is echter meer code nodig om hetzelfde resultaat te bereiken. Om eerlijk te zijn, als ik een grotere bekendheid had met C, zou de code misschien niet langer zijn dan het Go-voorbeeld.
echter, laten we zeggen dat dit het minimum is dat nodig is om hetzelfde resultaat te bereiken. Als je de twee vergelijkt, gezien de meer uitgebreide aard van C ‘ s syntaxis in vergelijking met Go, is het moeilijker te begrijpen.
wat meer is, als u geen eerdere ervaring had met C, ondanks een relatief vergelijkbare Cyclomatische Complexiteitsscore, wat zou uw perceptie zijn?
vindt u de code minder of ingewikkelder? Dit is een andere essentiële factor om de complexiteit van code te begrijpen.
de voordelen van het meten van Softwarecomplexiteit
er zijn vier kernvoordelen van het meten van codecomplexiteit, plus één extra.
betere Tests
door te weten hoeveel onafhankelijke paden er zijn door een stuk code, weten we hoeveel paden er zijn om te testen.
ik pleit trouwens niet voor 100% codedekking—dat is vaak een betekenisloze software-metriek. Ik pleit echter altijd voor een zo hoog mogelijk niveau van codedekking als praktisch en mogelijk is.
dus, door te weten hoeveel codepaden er zijn, kunnen we weten hoeveel paden we moeten testen. Als gevolg daarvan, je hebt een maat van het aantal tests nodig zijn, op een minimum, om ervoor te zorgen dat de code is gedekt.
verminderd risico
zoals het oude gezegde luidt:
het is moeilijker om code te lezen dan om het te schrijven.
wat meer:
- Code wordt veel meer gelezen dan geschreven
- een goede softwareontwikkelaar mag nooit worden beoordeeld aan de hand van de regels code die hij heeft geschreven (of gewijzigd), maar aan de hand van de kwaliteit van de code die hij heeft behouden.
aangezien u, door de complexiteit van de code te verminderen, het risico op het introduceren van defecten vermindert; of deze nu klein of groot zijn, licht gênant of faillissements-inducerend.
lagere kosten
wanneer het risico op potentiële defecten is verminderd, zijn er minder defecten te vinden en te verwijderen. Hierdoor dalen ook de onderhoudskosten.
we hebben allemaal de kosten gezien die gepaard gaan met het vinden van defecten in de verschillende stadia van de levensduur van een software, zoals in de onderstaande grafiek wordt geïllustreerd.
het is dus logisch dat, als we de complexiteit van onze code begrijpen en welke secties ingewikkelder zijn dan andere, we in een veel betere positie zijn om die complexiteit te verminderen.
dus door die complexiteit te verminderen, verminderen we de kans op het introduceren van defecten. Dat stroomt in alle stadia van het leven van een software.
grotere voorspelbaarheid
door de softwarecomplexiteit te verminderen, kunnen we meer voorspelbaarheid ontwikkelen. Wat ik daarmee bedoel is dat we beter in staat zijn om te zeggen—met vertrouwen—Hoe lang een gedeelte van de code duurt om te voltooien. Door dit te weten, kunnen we beter voorspellen hoe lang een vrijlating duurt om te verzenden.
op basis van deze kennis is het bedrijf of de organisatie beter in staat zijn doelen en verwachtingen te stellen, met name die welke direct afhankelijk zijn van deze software. Wanneer dit gebeurt, is het makkelijker om realistische budgetten, prognoses, enzovoort.
helpt ontwikkelaars te leren
helpt ontwikkelaars te leren en te groeien is het uiteindelijke voordeel van het begrijpen waarom hun code als complex wordt beschouwd. De tools die ik tot nu toe heb gebruikt om de complexiteit te beoordelen, doen dat niet.
wat zij doen is een algehele of gedetailleerde complexiteitsscore geven. Echter, een uitgebreide code complexiteit tool, zoals Codacy, doet.
in de schermafbeelding hierboven kunnen we zien dat van de zes genoemde bestanden één een complexiteit heeft van 30, een score die gewoonlijk als vrij hoog wordt beschouwd.
Cyclomatische complexiteit is een goede indicator om te begrijpen of de kwaliteit van de code verslechtert voor een bepaalde verandering. Cyclomatische complexiteit kan moeilijker te redeneren wanneer het kijken naar het of het vergelijken van hele modules gezien zijn oneindige schaal en niet gerelateerd aan de module grootte. Echter, iets dat je nuttig zou kunnen vinden is het bekijken van Codacy ‘ s bestandenlijst gesorteerd op prioriteit, wat je zal helpen begrijpen welke bestanden kandidaten zijn van slechte code kwaliteit, en vervolgens door gevolg hun modules.
dat is een Wrap
ook is dit een diepgaande discussie geweest over wat codecomplexiteit is, hoe het wordt beoordeeld, evenals de significante voordelen van het verminderen ervan. Hoewel er meer is om de complexiteit van code te begrijpen dan ik hier heb besproken, hebben we een lange weg afgelegd om het te begrijpen.
als dit de eerste keer is dat u over de term hoort of over een van de tools leert, moedig ik u aan om de gelinkte artikelen en tools te verkennen, zodat u meer te weten komt. Als u niet code In Go of C, dan google “code complexity tool” plus uw software Taal (s). Je zult zeker veel tools beschikbaar vinden.
voor meer tips om de kwaliteit van de code te verbeteren, Bekijk enkele andere blogberichten van Codacy.
ten slotte, als u een uitgebreide tool wilt voor het beoordelen van de kwaliteit van de code, en een tool die uw ontwikkelaars helpt te leren en te groeien, probeer dan Codacy.
Codacy wordt gebruikt door duizenden ontwikkelaars om miljarden regels code per dag te analyseren!
aan de slag gaan is eenvoudig – en gratis! Gebruik gewoon uw GitHub, Bitbucket of Google-account aan te melden.
AAN DE SLAG