Diversity w polskim IT
Miloš Živković
Miloš ŽivkovićSoftware Engineer @ enjoy.ing

3 metryki kodu doświadczonego deva

Wykrywaj kod niskiej jakości i szybko naprawiaj błędy m.in. dzięki złożoności cyklomatycznej.
10.12.20214 min
3 metryki kodu doświadczonego deva

Czy kod działa? Nic nie rób / Działa? Tak — idź dalej / Dokończ ASAP, wrócimy do refaktoryzacji...Nie lubisz tego słuchać. Zamiast tego powinieneś zaakceptować prawdę. „W miarę rozwoju systemu typu E jego złożoność wzrasta, o ile nie są prowadzone prace mające na celu jego utrzymanie lub redukcję” - prawa Lehmana.

Zajmij się problemami w kodzie dużo wcześniej i używaj dobrych metryk kodu, aby wykryć kod niskiej jakości.


A oto sposób, w jaki robią to doświadczeni programiści.

1. Dlaczego złożoność cyklomatyczna jest zła?

Złożoność cyklomatyczna jest metryką złożoności kodu. Większość narzędzi do analizy statycznej używa jej obecnie do przewidywania złożonego kodu.

Więcej branchowania — więcej złożonego kodu. Wysoka wartość metryki  — złożony kod. Większa złożoność cyklomatyczna  — więcej testów. Złożoność cyklomatyczna jest dobrą metryką na początek.

Analiza statyczna czasami nie jest adekwatna. Złożoność cyklomatyczna uogólnia mierzony kod. Ta sama metryka — inne rozumienie.

Jakiś przykład, w którym złożoność cyklomatyczna zawodzi?

Zagnieżdżenia. Zgodnie z kalkulatorem, złożoność zwiększa się o 1 dla każdej instrukcji if-else. Obliczenia dla konstrukcji zagnieżdżonych nie wystarczą.

if(c1)
 if(c2)
  if(c3) -> CyC = 3
switch cond ->
 case c1 : ... 
 case c2 : ...
 case c3 : ... -> CyC = 3


Nawet z takim napotkanym problemem, dalej jest to dobra metryka. Oto jeden z przykładów zastosowania w praktyce.

Jaka jest alternatywa? Metryki wyboistej drogi. Adam stwierdza, że kształt kodu, wskazuje na „smelly code”. Metryka wyboistej drogi mierzy zagnieżdżone konstrukcje (czyli wyboje), a metryka rośnie wraz z poziomem zagnieżdżenia.

„Liczby bezwzględne (złożoność cyklomatyczna) nie są dobrymi wskaźnikami złożoności kodu. To, jak ta złożoność jest rozłożona i jaki kształt ma kod, ma znaczenie” - A. Tornhil.


Wyboista droga skupia się na innych zmiennych, podczas gdy złożoność cyklomatyczna rozważa tylko przepływ sterowania. Metryka wyboistej drogi mierzy:

  • Liczbę linii pod jedną nierównością
  • Głębokość nierówności
  • Liczba wybojów


„Najlepszy wskaźnik dla złożonego, drogiego i ryzykownego kodu” - A.Tornhil.

2. Zidentyfikuj aspekty jakości kodu


Jakie aspekty decydują o wysokiej jakości oprogramowania?
ISO 25010 jest modelem jakości produktu. Model ten standaryzuje jakość oprogramowania. Wybierz aspekt, ustal cel i znajdź odpowiednią metrykę.

3. Przyjrzyj się bliżej kontroli wersji

Używamy kontroli wersji do zarządzania zmianami w kodzie. Przywracasz zły commit. Kopiujesz commity z pomocą komendy cherry-pick… Jednak brakuje nam tutaj jeszcze jednej funkcji.

Możesz użyć kontroli wersji do mierzenia jakości kodu. Połącz kontrolę wersji wraz ze złożonością kodu. Użyj korelacji do pomiaru jakości kodu.

Częste zmiany kodu wpływają na złożoność. Adam bada taką opcję i prezentuje wszystko na wykresie. Możemy na nim zauważyć, że niewielkie zmiany powodują wzrost złożoności. Użyj tej metryki, aby znaleźć kod niskiej jakości.

Naprawianie hotspotów w kodzie ma duży wpływ na jego jakość, a w większości baz kodu rozmieszczenie hot spotów jest takie samo.  Pliki o najmniejszej liczbie zmian mają niewielki wpływ na ogólną jakość kodu.

Michael opracował to oprogramowanie, aby znaleźć hotspoty kodu. Kontrola wersji daje szersze spojrzenie niż statyczna analiza kodu.

Adam używa tej metryki, aby wymusić ciągłe ulepszanie. Możesz zautomatyzować review kodu, zarządzać kondycją kodu i poprawiać jego jakość.

Tell, don’t ask

Mów, nie pytaj obiektów - Andy Hunt i Dave Thomas


Zła enkapsulacja tworzy kod proceduralny. Pytasz o stan obiektu, otrzymujesz wyniki i pracujesz z nimi. Proceduralny kod szkodzi zasadom programowania obiektowego.

Zła enkapsulacja tworzy gadatliwe oprogramowanie. Dodanie getterów i setterów odsłania obiekty, a takie odsłonięcie tworzy ścisłe sprzężenie. Zmiana w jednym obiekcie wywołuje szereg innych zmian.

Mniej gadatliwych obiektów — luźniejsza zależność oprogramowania. Ukrywasz stan wewnętrzny, pozostawiasz cienki interfejs i wymuszasz luźne zależności.

Pytając dużo o stan wewnętrzny, odsuwamy się od domeny problemu.

radio.tuners.volume_tuner.up();
vs.
radio.volumeUp();


Drugi przykład nie wysyła zapytań do stanu wewnętrznego. Ale pierwszy już tak. Klient wie teraz, co posiada obiekt radio.  Wewnętrzny stan, o który nie martwi się element wywołujący.

Jaka metryka wyłania nam się z zasady TellDontAsk? Odległość zależności.

Ta metryka mierzy wykorzystanie zwróconych obiektów. Im więcej używasz zwróconych obiektów, tym większa odległość. Większa odległość zależności — ciaśniejsze zależności.

Jegor używa tej metryki do znalezienia ścisłych zależności. Ono jednak nie trzyma się zasady TellDontAsk. Wręcz przeciwnie, kod ze ścisłymi zależnościami nie pyta o wiele. Użyj tej metryki, aby znaleźć kod ze ścisłym zależnościami.

Doświadczeni programiści używają również innych metryk. Używają czasu cyklu, czasu realizacji pull requesta, czasu realizacji QA. Celem jest szybszy development przy uruchamianiu. Ta metryka usunie blokery, jednak kod może na tym ucierpieć.

Niedoświadczeni programiści używają metryk adhoc. Ty nie powinieneś.


Oryginał tekstu w języku angielskim możesz przeczytać tutaj.

<p>Loading...</p>