Dzięki pytaniu na Code Review doszedłem do małego nieporozumienia (co w zasadzie jest okazją do nauczenia się czegoś) na temat tego, czym dokładnie jest złożoność cykliczna dla poniższego kodu.
public static void main(String[] args) {
try {
thro();
thro();
thro();
thro();
thro();
thro();
thro();
}
catch (NullPointerException e) {
}
}
private static Random random = new Random();
public static void thro() throws NullPointerException {
if (random.nextBoolean())
throw new NullPointerException();
System.out.println("No crash this time");
}
Pisząc ten kod w Eclipse i używając wtyczki Eclipse , mówi mi, że złożoność cykliczna McCabe dla głównej metody wynosi 2, a dla thro
metody 2.
Jednak ktoś inny mówi mi, że złożoność wywoływania thro
wielokrotnego jest number of calls * method complexity
, i dlatego twierdzi, że złożoność głównej metody wynosi 7 * 2 = 14.
Czy mierzymy różne rzeczy? Czy oboje możemy mieć rację? A jaka jest tutaj rzeczywista złożoność cyklomatyczna?
metrics
cyclomatic-complexity
Simon Forsberg
źródło
źródło
Odpowiedzi:
Kiedy rozumiał prawidłowo, cykliczna Złożoność z
main
wynosi 8 - to liczba liniowo niezależne ścieżki przez kod. Albo dostajesz wyjątek w jednym z siedmiu wierszy, albo żaden, ale nigdy więcej niż jeden. Każdy z tych możliwych „punktów wyjątku” odpowiada dokładnie jednej innej ścieżce w kodzie.Myślę, że kiedy McCabe wynalazł tę metrykę, nie miał języków programowania z myślą o obsłudze wyjątków.
źródło
main
metody?Będąc „drugim facetem”, odpowiem tutaj i sprecyzuję to, co mówię (co nie było szczególnie precyzyjne w stosunku do innych formuł).
Korzystając z powyższego przykładu kodu, obliczam złożoność cykliczną jako 8 i mam w kodzie komentarze, aby pokazać, jak to obliczam. Aby opisać ścieżki Rozważę udanej pętlę przez wszystkich tych
thro()
połączeń jak „” „głównej ścieżki kodu” (lub „CP = 1”):Tak więc liczę 8 ścieżek kodu w tej głównej metodzie, która według mnie jest złożonością cykliczną wynoszącą 8.
Mówiąc językiem Java, każdy mechanizm wyjścia z funkcji liczy się do jej złożoności, więc metoda, która ma stan powodzenia, i rzuca, na przykład, być może do 3 wyjątków, ma 4 udokumentowane ścieżki wyjścia.
Złożoność metody wywołującej taką funkcję to:
Sądzę, że należy wziąć pod uwagę inne kwestie: moim zdaniem
catch
klauzula nie przyczynia się do złożoności metody,catch
jest po prostu celemthrows
gałęzi, a zatem blokiem wychwytywania, który jest celem wieluthrow
s, zlicza 1 raz dla każdegothrow
, i nie tylko raz na wszystko.źródło
catch (Throwable t) {...
to myślę, że nie ma znaczenia, ile wyjątków deklaruje zgłosić .