o explicație aprofundată a complexității Codului

nu este un cod secret este un lucru complicat de scris, depanat și întreținut, care este necesar pentru o calitate software ridicată. Mai mult, complexitatea ridicată a codului aduce cu sine un nivel mai ridicat de defecte de cod, ceea ce face ca Codul să fie mai costisitor de întreținut.

deci, prin reducerea complexității codului, putem reduce numărul de erori și defecte, împreună cu costul său de viață. Ce este codul complex? Cum putem evalua în mod obiectiv cât de complexă este o bucată de cod, fie că este o întreagă bază de cod sau o funcție mică?

în acest articol, voi parcurge trei valori de complexitate pentru evaluarea complexității codului. Acestea sunt:

  • complexitatea Cyclomatic
  • declarație comutator și complexitatea condiție logică
  • Developer skill

voi merge, de asemenea, prin unele dintre beneficiile de evaluare și înțelegere complexitatea Cod.

complexitate Ciclomatică

în 1976, Thomas McCabe Snr a propus o metrică pentru calcularea complexității codului, numită complexitate Ciclomatică. Este definit ca:

o măsură cantitativă a numărului de căi liniar independente prin codul sursă al unui program…calculat folosind graficul fluxului de control al programului.

dacă nu sunteți familiarizat cu un grafic de control al fluxului:

este o reprezentare, folosind notația grafică, a tuturor căilor care ar putea fi traversate printr-un program în timpul execuției sale.

a spus mai direct, cu cât sunt mai puține căi printr-o bucată de cod și cu cât sunt mai puțin complexe aceste căi, cu atât complexitatea Ciclomatică este mai mică. Ca urmare, codul este mai puțin complicat. Pentru a demonstra metrica, să folosim trei exemple de cod Go, oarecum arbitrare.

exemplul unu

func main() { fmt.Println("1 + 1 =", 1+1)}

deoarece există o singură cale prin funcție, are un scor de complexitate Ciclomatică de 1, pe care îl putem găsi rulând gociclo pe ea.

exemplul doi

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) }}

în acest exemplu, recuperăm anul, luna și ziua curente. Cu aceste informații, verificăm apoi dacă data curentă este 10 noiembrie 2018 cu o condiție if/else.

dacă este, atunci codul imprimă ” Happy go day!”la consolă. Dacă nu este, atunci imprimă „luna curentă este” și numele lunii curente. Exemplul de cod se face mai complicat ca în cazul în care condiția este compusă din trei sub-condiții. Având în vedere acest lucru, are un scor de complexitate mai mare de 4.

exemplul trei

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.") }}

în acest exemplu, tipărim luna curentă, pe baza valorii month, preluată de la apel la time.Now().Date(). Există șapte căi prin funcție, una pentru fiecare dintre declarațiile de caz și una pentru implicit.

ca urmare, complexitatea sa Ciclomatică este 7. Dacă am fi contabilizat toate lunile anului, împreună cu un implicit, totuși, scorul său ar fi paisprezece. Acest lucru se întâmplă deoarece Gociclo folosește următoarele reguli de calcul:

1 este complexitatea de bază a unei funcții
+1 pentru fiecare ‘dacă’,’ pentru’, ‘caz’, ‘&&’ sau ‘||’

folosind aceste trei exemple, putem vedea că, având o metrică standard pentru calcularea complexității codului, putem evalua rapid cât de complexă este o bucată de cod.

de asemenea, putem vedea cât de diferite secțiuni complexe de cod sunt în comparație între ele. Cu toate acestea, complexitatea Ciclomatică nu este suficientă pe cont propriu.

declarație de comutare și complexitatea stării logice

următorul evaluator al complexității codului este instrucțiunea de comutare și complexitatea stării logice. În exemplul de cod de mai jos, am luat al doilea exemplu Go și împărțit compusul dacă condiție în trei condiții imbricate; una pentru fiecare dintre condițiile originale.

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)}

care este mai ușor de înțeles (sau mai puțin complicat), cel original sau acesta? Acum, să ne bazăm pe acest lucru, luând în considerare următoarele trei întrebări.

  • ce-ar fi dacă am avea, așa cum facem mai sus, mai multe condiții if și fiecare dintre ele ar fi destul de complexe?
  • ce se întâmplă dacă am avea mai multe condiții și codul din corpul fiecăruia ar fi destul de complex?
  • codul ar fi mai ușor sau mai greu de înțeles?

este corect să spunem că cu cât este mai mare numărul de condiții imbricate și cu cât este mai mare nivelul de complexitate în aceste condiții, cu atât este mai mare complexitatea codului.

nivelul de calificare al dezvoltatorului de Software

Ce zici de nivelul de calificare al dezvoltatorului? Aruncați o privire la versiunea C a celui de-al doilea exemplu Go de mai jos.

#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); }}

tehnic, face ceea ce fac celelalte exemple. Cu toate acestea, este nevoie de mai mult cod pentru a obține același rezultat. Pentru a fi corect, dacă am avut o mai mare familiaritate cu C, codul ar putea fi nu mai mult decât exemplul Go.

cu toate acestea, să spunem că acesta este minimul necesar pentru a obține același rezultat. Dacă comparați cele două, având în vedere natura mai detaliată a sintaxei lui C în comparație cu Go, este mai greu de înțeles.

mai mult, dacă nu ați avea experiență anterioară cu C, în ciuda unui scor de complexitate Ciclomatică relativ similar, care ar fi percepția voastră?

ați considera Codul mai puțin sau mai complicat? Deci, acesta este un alt factor esențial în înțelegerea complexității codului.

avantajele măsurării complexității Software-ului

există patru beneficii de bază ale măsurării complexității codului, plus unul suplimentar.

teste mai bune

știind câte căi independente există printr-o bucată de cod, știm câte căi sunt de testat.

nu pledez pentru acoperirea codului 100% apropo—aceasta este adesea o metrică software fără sens. Cu toate acestea, susțin întotdeauna un nivel cât mai ridicat de acoperire a codului, atât practic, cât și posibil.

deci, știind câte căi de cod există, putem ști câte căi trebuie să testăm. Ca rezultat, aveți o măsură de cât de multe teste sunt necesare, la un nivel minim, pentru a se asigura că codul este acoperit.

risc redus

după cum spune vechea zicală:

este mai greu să citești codul decât să-l scrii.

ce e mai mult:

  1. codul este citit mult mai mult decât este scris
  2. un dezvoltator de software bun nu ar trebui niciodată evaluat prin liniile de cod pe care le-au scris (sau le-au schimbat), ci prin calitatea codului pe care l-au menținut.

având în vedere că, prin reducerea complexității codului, reduceți riscul de a introduce defecte; indiferent dacă sunt mici sau mari, ușor jenante sau care provoacă faliment.

costuri mai mici

când riscul de defecte potențiale este redus, există mai puține defecte de găsit și eliminat. Ca urmare, costul de întreținere se reduce și el.

cu toții am văzut și suntem familiarizați cu costurile asociate cu găsirea defectelor în diferitele etape ale vieții unui software, așa cum este exemplificat în graficul de mai jos.

creșterea costului defectelor

deci, are sens că, dacă înțelegem complexitatea codului nostru și care secțiuni sunt mai complicate decât altele, atunci suntem într-o poziție mult mai bună pentru a reduce complexitatea menționată.

deci, prin reducerea acestei complexități, reducem probabilitatea de a introduce defecte. Care curge în toate etapele vieții unui software.

predictibilitate mai mare

prin reducerea complexității software-ului, ne putem dezvolta cu o predictibilitate mai mare. Ceea ce vreau să spun prin asta este că suntem mai capabili să spunem—cu încredere—cât durează o secțiune de cod pentru a finaliza. Știind acest lucru, suntem mai în măsură să prezică cât timp o eliberare ia pentru a navei.

pe baza acestor cunoștințe, afacerea sau organizația este mai capabilă să-și stabilească obiectivele și așteptările, în special cele care depind direct de software-ul menționat. Când se întâmplă acest lucru, este mai ușor să stabiliți bugete realiste, previziuni și așa mai departe.

ajută dezvoltatorii să învețe

ajutarea dezvoltatorilor să învețe și să crească este beneficiul final al înțelegerii de ce codul lor este considerat complex. Instrumentele pe care le-am folosit pentru a evalua complexitatea până în acest moment nu fac asta.

ceea ce fac este să ofere un scor general sau granular de complexitate. Cu toate acestea, un instrument cuprinzător de complexitate a codului, cum ar fi Codacy, o face.

lista complexității fișierelor

în captura de ecran de mai sus, putem vedea că, din cele șase fișiere enumerate, unul are o complexitate de 30, un scor considerat de obicei destul de mare.

complexitatea Ciclomatică este un indicator excelent pentru a înțelege dacă calitatea codului se deteriorează pentru orice modificare dată. Complexitatea ciclomatică poate fi mai greu de raționat atunci când o privim sau comparăm module întregi, având în vedere scara sa infinită și nefiind legată de dimensiunea modulului. Cu toate acestea, ceva pe care l-ați putea găsi util este să vă uitați la lista de fișiere Codacy sortată după prioritate, ceea ce vă va ajuta să înțelegeți ce fișiere sunt candidați de calitate slabă a codului și apoi, prin consecință, modulele lor.

aceasta este o folie

de asemenea, aceasta a fost o discuție aprofundată despre complexitatea codului, modul în care este evaluat, precum și beneficiile semnificative ale reducerii acestuia. Deși există mai multe în înțelegerea complexității codului decât am acoperit aici, am parcurs un drum lung până la înțelegerea acestuia.

dacă este prima dată când auziți despre termen sau aflați despre oricare dintre instrumente, vă încurajez să explorați articolele și instrumentele legate, astfel încât să aflați mai multe. Dacă nu codați în Go sau C, atunci google „Code complexity tool” plus limba(limbile) software-ului. Sunteți sigur că veți găsi multe instrumente disponibile.

pentru mai multe sfaturi pentru îmbunătățirea calității codului, consultați alte postări de blog de la Codacy.

în cele din urmă, dacă doriți un instrument cuprinzător pentru evaluarea calității codului și unul care să vă ajute dezvoltatorii să învețe și să crească, atunci încercați Codacy.

Codacy este folosit de mii de dezvoltatori pentru a analiza miliarde de linii de cod în fiecare zi!

Noțiuni de bază este ușor – și gratuit! Utilizați contul GitHub, Bitbucket sau Google pentru a vă înscrie.

ÎNCEPEȚI

Lasă un răspuns

Adresa ta de email nu va fi publicată.