Czy metody iteracyjne, które są powszechnie spotykane w nowoczesnych językach, takich jak C #, JavaScript i (mam nadzieję) w Javie 8, zmniejszają wpływ cykliczności złożoności na zrozumiałość i obsługę kodu?
Na przykład w C # możemy mieć następujący kod:
List<String> filteredList = new List<String>();
foreach (String s in originalList){
if (matches(s)){
filteredList.add(s);
}
}
Ma to prostą cykliczną złożoność 2.
Możemy z łatwością ponownie napisać to jako:
List<String> filteredList = originalList.where(s => matches(s));
Który ma prostą cykliczną złożoność równą 0.
Czy to faktycznie powoduje, że kod jest bardziej obsługiwany? Czy istnieją jakieś rzeczywiste badania na ten temat?
cyclomatic-complexity
Krzyż
źródło
źródło
Odpowiedzi:
Domyślam się, że właśnie podzieliłeś / przeniosłeś złożoność. Zmniejszyło się, ponieważ nie liczysz implementacji
.where()
w swoim CC.Ogólne CC naprawdę się nie zmieniło, CC własnego kodu zmniejszyło się, tylko dlatego, że zostało teraz przeniesione do kodu frameworka.
Powiedziałbym, że jest łatwiejsza w utrzymaniu. Jeśli jest to cecha języka, użyj go. To nie jest „och, rozumiem, to sprytna sztuczka” , której używasz, tylko prosta wbudowana funkcja podobna do redukcji.
źródło
Wszystko, co robisz, to podkreślenie błędu w cykliczności złożoności jako metryki, złożoność kodu naprawdę się nie zmieniła. Masz wyraźną gałąź w pierwszym przykładzie i musisz zrozumieć, że istnieje domniemana gałąź w drugim przykładzie. Drugi jest jaśniejszy i łatwiejszy do zrozumienia, pod warunkiem, że rozumiesz składnię, a ponieważ używa ona mniej podstawowej składni, co może być problemem.
źródło
where
prawdopodobnie pochodzi z frameworka. Myślę, że złożoność cykliczna jako metryka jest przydatna nawet tutaj, ponieważ dzielenie funkcji na kilka nie zmniejsza ogólnej złożoności systemu (w rzeczywistości często ją zwiększa, choćby nieznacznie), ale pomaga określić, kiedy element systemu staje się zbyt skomplikowany i musi zostać zepsuty.Aby obiektywnie odpowiedzieć na to pytanie, potrzebowalibyśmy pewnego rodzaju mierników do utrzymania. Sama złożoność cykliczna nie jest miarą łatwości konserwacji, ale jest składnikiem niektórych wskaźników, które mają mierzyć łatwość konserwacji. Na przykład formuła indeksu konserwacji jest następująca:
gdzie
G
jest cykliczna złożoność danego kodu. Dlatego zmniejszenie cyklicznej złożoności fragmentu kodu z definicji poprawia Indeks Konserwowalności kodu i inne mierniki, które podobnie wykorzystują złożoność cykliczną .Trudno powiedzieć, czy proponowana przez Ciebie zmiana sprawia, że program wydaje się łatwiejszy do utrzymania dla programistów; to prawdopodobnie zależy od tego, jak dobrze znają (w twoim przypadku)
where
metodę.źródło
(>_<)
Ponieważ wykazano, że złożoność cykliczna (CC) jest bardzo silnie skorelowana z rozmiarem kodu, „do tego stopnia, że można powiedzieć, że CC nie ma absolutnie żadnej własnej mocy wyjaśniającej”. tak naprawdę pytasz, czy „metody iteracyjne, które są powszechnie spotykane w nowoczesnych językach, takich jak C #, JavaScript i (mam nadzieję) w Javie 8, zmniejszają wpływ rozmiaru kodu na zrozumiałość i obsługę kodu”.
W tym momencie można mieć nadzieję, że odpowiedź będzie oczywista. Od dziesięcioleci wiadomo, że krótszy kod jest ogólnie łatwiejszy do zrozumienia, utrzymania i wsparcia.
źródło
Jeśli mówisz o surowej statystyce złożoności cyklomatycznej, na pewno. Właśnie nuknąłeś go od 2 do 0. Jeśli idziesz liczbami, czysty zysk przez całą drogę.
Jednak z praktycznego punktu widzenia (czytaj: człowiek) argumentowałbym, że tak naprawdę zwiększyłeś złożoność o 2. Jednym z nich jest fakt, że teraz inny programista musi przynieść lub zdobyć wiedzę na temat płynnej składni LINQ, aby to zrozumieć kod.
Kolejny punkt zwiększonej trudności wynika ze zrozumienia wyrażeń lambda; chociaż w tym przypadku Lambda jest dość prosta , należy wprowadzić pewne zmiany paradygmatu, aby w pełni je docenić.
Ten przypadek użycia
a.where(x => matches(x, arg))
nie jest straszny, i szczerze mówiąc, jest to świetny sposób, aby jakiś współpracownik po raz pierwszy zobaczył i pracował z wyrażeniami LINQ i Lambda (tak naprawdę przedstawiłem samouczek na temat LINQ / Lambdas niektórym byłym współpracownikom używającym tego i inne zestawy kodu, z wielkim skutkiem.) Jednak ich użycie wymaga pewnej wiedzy.Zalecam ostrożność, ponieważ widziałem przypadki, w których refaktor LINQ jest znacznie gorszy do odczytania niż to, czym
foreach
staje się ta pętla.źródło
Subiektywnie zależy to od odbiorców programistów, jeśli rozumieją wyrażenia lambda;
jest szybszy do zrozumienia i może nieco łatwiejszy. Byłbym bardziej zaniepokojony używaniem s i match (). Ani też nie jest samoopisowe, coś w rodzaju;
Lub
daje deweloperowi bardziej znaczące informacje i jest łatwiejszy do analizy, bez konieczności zagłębiania się w funkcję match () w celu ustalenia, które dopasowanie jest wykonywane.
Utrzymywalność to nie tylko umiejętność zrozumienia kodu, ale przede wszystkim szybkość i dokładność, z jaką można go zrozumieć.
źródło