Was bedeutet die zyklomatische Komplexität meines Codes?

42

Ich bin neu in der statischen Analyse von Code. Meine Anwendung hat eine zyklomatische Komplexität von 17.754. Die Anwendung selbst besteht nur aus 37.672 Codezeilen. Ist es gültig zu sagen, dass die Komplexität basierend auf den Codezeilen hoch ist? Was genau sagt mir die zyklomatische Komplexität?

Wütender Vogel
quelle
Das hängt ganz davon ab, was Sie tun. Wenn Sie versuchen, etwas Einfaches zu tun, dann ist es sehr, sehr hoch. Sie sollten dieses Verhältnis zum Beispiel in "Hallo Welt" nicht haben.
Cwallenpoole

Antworten:

48

Was genau sagt mir die zyklomatische Komplexität?

Die zyklomatische Komplexität ist kein Maß für Codezeilen, sondern die Anzahl der unabhängigen Pfade durch ein Modul. Ihre zyklomatische Komplexität von 17.754 bedeutet, dass Ihre Anwendung über 17.754 eindeutige Pfade verfügt. Dies hat einige Auswirkungen, in der Regel darauf, wie schwierig es ist, Ihre Anwendung zu verstehen und zu testen. Die zyklomatische Komplexität ist beispielsweise die Anzahl der Testfälle, die erforderlich sind, um eine 100% ige Zweigabdeckung zu erreichen, vorausgesetzt, die Tests sind gut geschrieben.

Ein guter Ausgangspunkt könnte der Wikipedia-Artikel über zyklomatische Komplexität sein . Es enthält einige Pseudocode-Ausschnitte und einige Grafiken, die zeigen, worum es bei der zyklomatischen Komplexität geht. Wenn Sie mehr wissen möchten, können Sie auch McCabes Artikel lesen, in dem er die zyklomatische Komplexität definiert .

Meine Anwendung hat eine zyklomatische Komplexität von 17.754 Codezeilen. Die Anwendung selbst besteht nur aus 37.672 Codezeilen. Ist es gültig zu sagen, dass die Komplexität aufgrund der Codezeilen hoch ist?

Überhaupt nicht. Eine Anwendung mit wenigen Codezeilen und einer hohen Anzahl von in Schleifen verschachtelten Bedingungen kann eine extrem hohe zyklomatische Komplexität aufweisen. Andererseits kann eine Anwendung mit wenigen Bedingungen eine geringe zyklomatische Komplexität aufweisen. Das ist eine große Vereinfachung, aber ich denke, es bringt die Idee rüber.

Ohne mehr über die Funktionsweise Ihrer Anwendung zu wissen, ist es möglicherweise normal, dass die zyklomatische Komplexität höher ist. Ich würde jedoch vorschlagen, die zyklomatische Komplexität auf Klassen- oder Methodenebene zu messen, anstatt nur auf Anwendungsebene. Dies ist konzeptionell ein wenig besser zu handhaben - es ist einfacher, die Pfade durch eine Methode zu visualisieren oder zu konzipieren als Pfade durch eine große Anwendung.

Thomas Owens
quelle
36

Durch die zyklomatische Komplexität können Sie feststellen, ob Ihr Code überarbeitet werden muss. Der Code wird analysiert und eine Komplexitätszahl bestimmt. Die Komplexität wird durch Verzweigung (if-Anweisungen usw.) bestimmt. Die Komplexität kann auch die Verschachtelung von Schleifen usw. und andere Faktoren berücksichtigen, je nach dem verwendeten Algorithmus.

Die Nummer ist auf der Methodenebene nützlich. Auf höheren Ebenen ist es nur eine Zahl.

Eine Zahl von 17.754 gibt die Komplexität auf Projektebene (Gesamtcode) an, die nicht so viel Bedeutung hat.

Durch das Heruntersuchen der Komplexität auf Klassen- und Methodenebene werden Bereiche des Codes bestimmt, die in kleinere Methoden umgestaltet oder neu gestaltet werden müssen, um die Komplexität zu verringern.

Betrachten Sie eine CASEAussage mit 50 Fällen in einer Methode. Vielleicht hat jeder Staat eine andere Geschäftslogik. Das ergibt eine zyklomatische Komplexität von 50. Es gibt 50 Entscheidungspunkte. Die CASE-Anweisung muss möglicherweise mithilfe eines Factory-Musters neu entworfen werden, um die Verzweigungslogik zu entfernen. Manchmal können Sie eine Umgestaltung vornehmen (die Methode in kleinere Teile aufteilen), und in einigen Fällen wird die Komplexität nur durch eine Neugestaltung verringert.

Im Allgemeinen gilt für die Komplexität auf Methodenebene Folgendes:

  • <10 Pflegeleicht
  • 11-20 Schwieriger zu pflegen
  • 21+ Kandidaten für Refactoring / Redesign

Bedenken Sie auch, dass höhere Komplexitäten den Komponententest erschweren.

Die höchste Komplexität, die ich bei einer einzelnen Methode gesehen habe, war 560. Es waren ungefähr 2000 Zeilen if-Anweisungen in einer Methode. Grundsätzlich nicht zu warten, nicht zu testen, voller potenzieller Fehler. Stellen Sie sich alle für diese Verzweigungslogik erforderlichen Komponententestfälle vor! Nicht gut.

Versuchen Sie, alle Methoden unter 20 zu halten, und stellen Sie fest, dass die Umgestaltung einer Methode mit Kosten verbunden ist, um sie weniger komplex zu machen.

Jon Raynor
quelle
Das ist eine bessere Antwort.
Pacerier
2
@ Pacerier In diesem Fall stimme einfach der Antwort zu;).
Zero3,
> "Im Allgemeinen für Komplexität auf Methodenebene" Zitieren?
Benny Bottema
Eine der ursprünglichen Anwendungen von McCabe bestand darin, die Komplexität der Routinen während der Programmentwicklung zu begrenzen. er empfahl Programmierern, die Komplexität der von ihnen entwickelten Module zu zählen und sie in kleinere Module aufzuteilen, wenn die zyklomatische Komplexität des Moduls 10 überschreitet.
Jon Raynor
"Die CASE-Anweisung muss möglicherweise mithilfe eines Factory-Musters umgestaltet werden, um die Verzweigungslogik zu beseitigen." Warum? Das beseitigt nicht die Komplexität der Logik; es verbirgt es nur und macht es weniger offensichtlich und daher schwieriger zu warten.
Mason Wheeler
1

Dies ist die Anzahl der unterschiedlichen Pfade in Ihrer Anwendung. Lesen Sie diesen IBM Artikel zu CC .

Es scheint hoch, aber in Ihrem Fall ist es die Hinzufügung des CC aller Ihrer Methoden aller Ihrer Klassen und Methoden. Meine Beispiele sind sehr umfangreich, da ich nicht weiß, wie Ihr Code aufgebaut ist, aber Sie können auch eine Monstermethode mit 37672 Codezeilen oder 3767 Methoden mit etwa 10 Codezeilen verwenden. Ich meine, dass dieser Indikator auf Anwendungsebene nicht viel bedeutet, aber auf Methodenebene kann er Ihnen helfen, Ihren Code in kleinere Methoden zu optimieren / umzuschreiben, damit sie weniger fehleranfällig sind.

Was ich persönlich oft gelesen habe, ist, dass Methoden mit einem CC von mehr als 10 ein höheres Fehlerrisiko aufweisen.

Ich verwende Sonar , um die Codequalität meiner Anwendungen zu testen. Standardmäßig wird eine Warnung ausgegeben, wenn Sie Methoden mit +10 CC verwenden. Trotzdem kann das nichts bedeuten. Ein konkretes Beispiel: Wenn Sie mit Eclipse eine equalsMethode generieren , die auf den Eigenschaften Ihrer Bohne basiert, springt der CC sehr schnell über das Dach ...

Jalayn
quelle
1
Die Standardeinstellung von PMD ist die Warnung vor einer zyklomatischen Komplexität von 10. Wenn Sie die Komplexität auf der Ebene der einzelnen Methoden betrachten, können Sie auch Methoden außer Acht lassen, die gute Gründe für einen hohen CC-Wert haben, z. B. generierte equalsMethoden.
Thomas Owens
Ich war mir nicht sicher, also habe ich nachgesehen, aber Sonar verwendet intern PMD, um diese Messung zu erhalten. Also macht alles Sinn :-)
Jalayn
-1

Es hängt davon ab, welches Tool Sie verwendet haben. Einige der Open-Source-Tools werden als Modul oder als Modul mit einer anderen Strukturebene bezeichnet. Je größer ein Projekt wird, desto höher ist die zyklomatische Komplexität. Nach meinem persönlichen Verständnis sollte es sich jedoch um eine Funktionsbasis handeln. Je größer ein Projekt wird, desto mehr Funktionen hat es.

Ich empfehle Ihnen, das Tool namens Lizard zu verwenden. Sie können den Ressourcencode finden und die ZIP-Datei bei github herunterladen. Es gibt auch eine Online-Version, wenn Ihr Code nicht viele vertrauliche Informationen enthält.

Der aussagekräftige CCN, um den Sie sich kümmern sollten, basiert auf einer anderen Funktionsbasis als jeder anderen. Halten Sie außerdem die CCN jeder Funktion unber 15, um die ideale Reichweite zu erzielen.

Jiahang Li
quelle