to nie jest tajny kod to skomplikowana rzecz do napisania, debugowania i utrzymania, która jest niezbędna do wysokiej jakości oprogramowania. Co więcej, Wysoka złożoność kodu niesie ze sobą wyższy poziom wad kodu, dzięki czemu kod jest tańszy w utrzymaniu.
tak więc, zmniejszając złożoność kodu, możemy zmniejszyć liczbę błędów i defektów, wraz z kosztem ich żywotności. Czym dokładnie jest złożony kod? Jak obiektywnie ocenić, jak złożony jest fragment kodu, czy jest to cała baza kodu, czy jedna mała funkcja?
w tym artykule omówię trzy wskaźniki złożoności do oceny złożoności kodu. Są to:
- Cyclomatic complexity
- Switch statement and logic condition complexity
- Developer skill
omówię również niektóre korzyści płynące z oceny i zrozumienia złożoności kodu.
- złożoność Cyklomatyczna
- przykład jeden
- przykład dwa
- przykład trzy
- Instrukcja Switch i złożoność warunku logicznego
- Poziom umiejętności programisty
- korzyści płynące z pomiaru złożoności oprogramowania
- lepsze testy
- zmniejszone ryzyko
- niższe koszty
- większa przewidywalność
- pomaga programistom uczyć się
- to jest zawijanie
złożoność Cyklomatyczna
w 1976 roku Thomas McCabe Snr zaproponował metrykę do obliczania złożoności kodu, zwaną złożonością Cyklomatyczną. Jest zdefiniowany jako:
ilościowa miara liczby liniowo niezależnych ścieżek przez kod źródłowy programu…obliczona za pomocą grafu przepływu sterowania programu.
jeśli nie znasz wykresu przepływu sterowania:
jest to reprezentacja, przy użyciu notacji wykresowej, wszystkich ścieżek, które mogą być przemierzane przez program podczas jego wykonywania.
powiedział bardziej wprost, im mniej ścieżek przez kawałek kodu i im mniej skomplikowanych są te ścieżki, tym mniejsza złożoność Cyklomatyczna. W rezultacie kod jest mniej skomplikowany. Aby zademonstrować metrykę, użyjmy trzech, nieco arbitralnych, przykładów kodu Go.
przykład jeden
func main() { fmt.Println("1 + 1 =", 1+1)}
ponieważ istnieje tylko jedna ścieżka przez funkcję, ma ona Cyclomatic Complexity score 1, który możemy znaleźć, uruchamiając na niej gocyclo.
przykład dwa
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) }}
w tym przykładzie pobieramy bieżący rok, miesiąc i dzień. Dzięki tym informacjom sprawdzamy, czy aktualną datą jest 10 listopada 2018 r.z warunkiem if/else.
jeśli tak, to kod wyświetla ” Happy Go day!”do konsoli. Jeśli tak nie jest, wypisuje „bieżący miesiąc jest” i nazwę bieżącego miesiąca. Przykład kodu jest bardziej skomplikowany, ponieważ warunek if składa się z trzech pod-warunków. Biorąc to pod uwagę, ma wyższy wynik złożoności 4.
przykład trzy
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.") }}
w tym przykładzie drukujemy bieżący miesiąc na podstawie wartości month
, pobranej z wywołania do time.Now().Date()
. Istnieje siedem ścieżek przez funkcję, jedna dla każdej instrukcji case i jedna dla domyślnej.
w rezultacie jego złożoność Cyklomatyczna wynosi 7. Gdybyśmy jednak uwzględnili wszystkie miesiące roku, wraz z błędem, jego wynik byłby czternasty. Dzieje się tak, ponieważ Gocyclo używa następujących reguł obliczeniowych:
1 jest złożonością bazową funkcji
+1 dla każdego’ if’,’ for’, 'case’, '&&’ lub '||’
korzystając z tych trzech przykładów, możemy zobaczyć, że dzięki standardowemu wskaźnikowi do obliczania złożoności kodu, możemy szybko ocenić, jak złożony jest fragment kodu.
możemy również zobaczyć, jak różne złożone sekcje kodu są w porównaniu ze sobą. Jednak złożoność Cyklomatyczna sama w sobie nie wystarcza.
Instrukcja Switch i złożoność warunku logicznego
kolejnym oceniającym złożoność kodu jest instrukcja Switch i złożoność warunku logicznego. W poniższym przykładzie kodu wziąłem drugi przykład i podzieliłem złożony warunek if na trzy zagnieżdżone Warunki; po jednym dla każdego z pierwotnych warunków.
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)}
która jest łatwiejsza do zrozumienia (lub mniej skomplikowana), oryginalna, czy ta? Wykorzystajmy to, rozważając następujące trzy pytania.
- a gdybyśmy mieli, jak to robimy powyżej, wiele warunków if I każdy z nich był dość złożony?
- co by było, gdybyśmy mieli wiele warunków if, a kod w ciele każdego z nich był dość złożony?
- czy kod będzie łatwiejszy czy trudniejszy do zrozumienia?
można powiedzieć, że im większa liczba zagnieżdżonych warunków i im wyższy poziom złożoności w tych warunkach, tym większa złożoność kodu.
Poziom umiejętności programisty
co z poziomem umiejętności programisty? Spójrz na wersję C poniższego przykładu second Go.
#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); }}
technicznie robi to, co inne przykłady. Wymaga jednak więcej kodu, aby osiągnąć ten sam wynik. Szczerze mówiąc, gdybym miał większą znajomość C, kod może nie być dłuższy niż przykład Go.
powiedzmy jednak, że jest to minimum wymagane do osiągnięcia tego samego wyniku. Jeśli porównasz te dwa, biorąc pod uwagę bardziej gadatliwą naturę składni C w porównaniu do Go, trudniej to zrozumieć.
co więcej, gdybyś nie miał wcześniejszego doświadczenia z C, pomimo stosunkowo podobnego wyniku złożoności Cyklomatycznej, jakie byłoby twoje postrzeganie?
czy uważasz, że kod jest mniej lub bardziej skomplikowany? Jest to więc kolejny istotny czynnik w zrozumieniu złożoności kodu.
korzyści płynące z pomiaru złożoności oprogramowania
istnieją cztery podstawowe zalety pomiaru złożoności kodu, plus jedna dodatkowa.
lepsze testy
wiedząc, ile niezależnych ścieżek znajduje się w danym fragmencie kodu, wiemy, ile ścieżek jest do przetestowania.
nie opowiadam się za 100% pokryciem kodu-to często bezsensowna metryka oprogramowania. Jednak zawsze opowiadam się za tak wysokim poziomem pokrycia kodu, jak jest to zarówno praktyczne, jak i możliwe.
więc wiedząc, ile jest ścieżek kodu, możemy wiedzieć, ile ścieżek musimy przetestować. W rezultacie masz miarę, ile testów jest wymaganych, co najmniej, aby upewnić się, że kod jest objęty.
zmniejszone ryzyko
jak mówi stare powiedzenie:
trudniej jest odczytać kod niż go napisać.
co więcej:
- kod jest czytany znacznie częściej niż jest napisany
- dobry programista nigdy nie powinien być oceniany na podstawie linii kodu, które napisał (lub zmienił), ale na podstawie jakości kodu, który zachował.
biorąc pod uwagę, że zmniejszając złożoność kodu, zmniejszasz ryzyko wprowadzenia wad; niezależnie od tego, czy są małe, czy duże, nieco żenujące, czy wywołujące bankructwo.
niższe koszty
gdy ryzyko potencjalnych wad jest zmniejszone, jest mniej wad do znalezienia-i usunięcia. W rezultacie zmniejsza się również koszt konserwacji.
Wszyscy widzieliśmy i znamy koszty związane z wykrywaniem wad na różnych etapach życia oprogramowania, jak pokazano na poniższym wykresie.
ma więc sens, że jeśli rozumiemy złożoność naszego kodu i które sekcje są bardziej skomplikowane niż inne, jesteśmy w znacznie lepszej sytuacji, aby zmniejszyć wspomnianą złożoność.
tak więc zmniejszając tę złożoność, zmniejszamy prawdopodobieństwo wprowadzenia wad. To wpływa na wszystkie etapy życia oprogramowania.
większa przewidywalność
zmniejszając złożoność oprogramowania, możemy rozwijać się z większą przewidywalnością. Mam na myśli to, że jesteśmy w stanie lepiej powiedzieć-z pewnością-jak długo trwa Ukończenie sekcji kodu. Wiedząc o tym, jesteśmy w stanie lepiej przewidzieć, jak długo trwa wysyłka.
bazując na tej wiedzy firma lub organizacja jest w stanie lepiej wyznaczać swoje cele i oczekiwania, zwłaszcza te, które są bezpośrednio zależne od wspomnianego oprogramowania. Gdy tak się stanie, łatwiej jest ustawić realistyczne budżety, prognozy i tak dalej.
pomaga programistom uczyć się
pomoc programistom w nauce i rozwoju jest ostateczną korzyścią zrozumienia, dlaczego ich kod jest uważany za złożony. Narzędzia, których używałem do oceny złożoności do tej pory tego nie robią.
zapewniają ogólny lub ziarnisty wynik złożoności. Jednak narzędzie do kompleksowej złożoności kodu, takie jak Codacy, robi.
na powyższym zrzucie ekranu widzimy, że z sześciu wymienionych plików jeden ma złożoność 30, wynik zwykle uważany jest za dość wysoki.
złożoność Cyclomatic jest doskonałym wskaźnikiem, aby zrozumieć, czy jakość kodu pogarsza się dla danej zmiany. Złożoność Cyclomatic może być trudniejsza do rozumowania przy patrzeniu na nią lub porównywaniu całych modułów, biorąc pod uwagę jego nieskończoną skalę i brak związku z rozmiarem modułu. Jednak coś, co może okazać się przydatne, to przeglądanie listy plików Codacy posortowanej według priorytetu, co pomoże Ci zrozumieć, które pliki są kandydatami o złej jakości kodu, a w konsekwencji ich moduły.
to jest zawijanie
również była to dogłębna dyskusja na temat złożoności kodu, sposobu jego oceny, a także znaczących korzyści płynących z jego zmniejszenia. Chociaż zrozumienie złożoności kodu jest czymś więcej niż opisałem tutaj, przebyliśmy długą drogę do jego zrozumienia.
jeśli po raz pierwszy słyszysz o tym pojęciu lub poznajesz którekolwiek z narzędzi, zachęcam do zapoznania się z powiązanymi artykułami i narzędziami, abyś mógł dowiedzieć się więcej. Jeśli nie kodujesz W Go lub C, Następnie google „narzędzie złożoności kodu” oraz język(y) oprogramowania. Na pewno znajdziesz wiele dostępnych narzędzi.
aby uzyskać więcej wskazówek, jak poprawić jakość kodu, sprawdź inne posty na blogu Codacy.
wreszcie, jeśli potrzebujesz kompleksowego narzędzia do oceny jakości kodu, które pomoże programistom uczyć się i rozwijać, wypróbuj Codacy.
Codacy jest używany przez tysiące programistów do analizy miliardów linii kodu każdego dnia!
rozpoczęcie pracy jest łatwe – i bezpłatne! Wystarczy użyć swojego konta GitHub, Bitbucket lub Google, aby się zarejestrować.
ROZPOCZNIJ