Jak czytać i interpretować wybrane metryki statycznej analizy kodu?

Lines of code (LOC):

Opis:
Mierzy ilość linii kodu w rozpatrywanym typie.
Interpretacja:
Metryka ta może być używana jako wskaźnik za dużych metod i klas.

Comment lines of code (CLOC):

Opis:
Ilość linii komentarza.
Interpretacja:
Niska wartość może wskazywać na niedostateczne udokumentowanie kodu.

Halstead’s volume (V)

Opis:
Opisuje rozmiar implementacji algorytmu. Obliczanie V jest oparte na ilości wykonanych operacji i operandów przetwarzanych w algorytmie.
Interpretacja:
V funkcji powinna być zawarta pomiędzy 20 a 1000. Objętości wyższe niż 1000 dają do zrozumienia że funkcja prawdopodobnie robi zbyt dużo rzeczy. V pliku powinna być zawarta między 100 i 8000.

Comment Weight (CW)

Opis:
Stosunek między kodem logicznym a komentarzem.
Interpretacja:
Niska wartość stosunku między kodem logicznym, a komentarzem może wskazywać na niedostateczne udokumentowanie kodu.

Cyclomatic complexity (CC)

Opis:
Złożoność cyklomatyczna, metryka używana do obliczania złożoności metod lub procedur.
Uproszczona wersja metryki: CC = d +1
Gdzie: d – liczba węzłów decyzyjnych w grafie (w praktyce liczy się ilość instrukcji if, while, do, for, ?:, catch, switch, case i operatorów &&, ||).
Interpretacja:
Wysokie wartości metryki CC wskazują na to, że metoda jest zbyt skomplikowana, przez co zwiększa się prawdopodobieństwo wystąpienia błędu. Wartości 1-4 są uważana za dobre, 8-10 jako zalecane do refaktoryzacji, powyżej 11 konieczna jest refaktoryzacja.

Lack of Cohesion in Methods (LCOM)

Opis:
Jest to metryka mierząca spójność metod wewnątrz klasy.
Interpretacja:
Wysoka wartość metryki może wskazywać klasy, które mają przydzieloną zbyt dużą ilość obowiązków i są kandydatem do podziału na mniejsze. Klasa o wysokiej wartości LCOM może być bardziej narażona na błędy, jest trudniejsza w testowaniu.

Afferent coupling (Ca):

Opis:
Ca to liczba klas spoza rozpatrywanego pakietu, które zależą od klas w rozpatrywanym pakiecie.
Interpretacja:
Wysoka wartość tej metryki sugeruje w niejawny sposób dużą stabilność komponentu, ale także dużą odpowiedzialność względem zależnych typów.

Efferent coupling (Ce):

Opis:
Ce to liczba klas z rozpatrywanego pakietu, które zależą od klas w innych pakietach. Mierzy zatem podatność rozpatrywanego pakietu na zmiany w pakietach, od których zależy.
Interpretacja:
Wysokie wartości tej metryki wskazują na niestabilność pakietu – duża zależność od zewnętrznych klas.

Instability (I):

Opis:
I jest to względna podatność na zmiany. Metryka ta jest zdefiniowana za pomocą Ce i Ca.
Interpretacja:
Pakiety powinny się dzielić na dwie grupy:
– stabilne o wartości metryki I bliskiej 0, które ponoszą dużą odpowiedzialność
wobec innych komponentów.
– niestabilne o wartości metryki I bliskiej 1, które w dużej mierze zależą od
innych komponentów.

Analiza statyczna kodu

Analiza statyczna kodu – analiza struktury kodu źródłowego lub kodu skompilowanego bez jego uruchomienia.

Zastosowania:
– automatyczna ocena zmian w kodzie
– szybka, wstępna analiza otrzymanego projektu
– uzyskiwanie informacji o zgodności kodu z narzuconymi standardami
– wspieranie procesu code review
– wykrywanie słabych punktów projektów – miejsc wymagających refaktoryzacji.

Zalety:
– Szybkość działania – szybkie wykrywanie błędów, których naprawa jest prosta i mało kosztowna
– nie wymagają uruchamiania programu
– łatwe do zrównoleglenia
– Łatwość użycia – proste we wdrożeniu w cykl wytwarzania oprogramowania
– Automatyzacja – integracja z narzędziami continuous integrations
– Możliwości rozszerzania: własne reguły, wtyczki
– Dużo darmowych narzędzi
– Integracja z innymi narzędziami: serwery automatyzacji, IDE, kontrola wersji

Wady:
– Wymagany dostęp do źródeł
– Reguły wykrywają zazwyczaj proste błędy i nie są w stanie wyeliminować ręcznego sprawdzenia kodu
– Dużo szumu, zbyt czułe – duże prawdopodobieństwo zaklasyfikowanie poprawnego fragmentu jako błędu (false positive)
– Skomplikowane algorytmy i architektury bardzo ciężko jest analizować
– Każde narzędzie zazwyczaj pokrywa pewien zakres testów (do 14% błędów?!). Dlatego warto korzystać z kilku różnych skanerów kodu

Dlaczego analizować kod?
– zwiększenie wydajności i stabilności poprzez zasady oparte na dobrych praktykach,
– uniknięcie typowych błędów podczas programowania,
– dostarczenie struktury do zarządzania standardami kodu.
– wymuszenie zasad i standardów pisania kodu
– zwiększenie bezpieczeństwa poprzez kolejny etap testowania
– analizując sygnalizowane błędy można się sporo nauczyć na temat dobrych praktyk bezpiecznego programowania