Umgang mit zyklomatischer Komplexität in Java-Code

Umgang mit zyklomatischer Komplexität in Java-Code Debadatta Mishra EinführungMöglicherweise haben Sie den Begriff Codeverwaltung in Java gehört. Es bezieht sich darauf, wie Sie Ihren Quellcode so verwalten, dass er zum Zeitpunkt der Wartung bis zu einem gewissen Grad einfacher zu handhaben ist. Es ist immer richtig, dass sich die Anforderungen von Zeit zu Zeit ändern und der Quellcode bis zu einem gewissen Grad geändert wird. Möglicherweise haben Sie gesehen, dass ein bestimmtes Modul sehr riskant zu berühren scheint. Einige Leute sagen, dass dieses Modul gut funktioniert, aber Code nicht verwaltbar ist. Es kommt in den meisten IT-Branchen vor, es kann mehrere Gründe geben. Ich kann jedoch sagen, dass das Schreiben von Code eine Kunst ist. Einige Entwickler nehmen diese Angelegenheit sehr ernst. Möglicherweise finden Sie die Gelegenheit zur Codeüberprüfung und Codeüberprüfung in der Organisation. Das Schreiben des besseren Codes geht über den Rahmen dieses Artikels hinaus.In diesem Artikel möchte ich mich auf die zyklomatische Komplexität konzentrieren, die im Quellcode viel häufiger vorkommt. Es ist auch wahr, dass Sie sich von diesem Konzept fernhalten können. Der Grundgedanke ist der Umgang mit der Codekomplexität.

Technische Daten

Cyclomatic Complexity ist ein Konzept zur Metrik, das von Thomas McCabe geprägt wurde. Es gibt den Begriff der strukturellen Komplexität einer Methode oder eines Quellcodes. Grundsätzlich werden die verschiedenen Entscheidungs- und Bedingungsfälle behandelt. Wenn Sie einen Code schreiben, der mehrere logische Entscheidungen und Bedingungen enthält, müssen Sie sich um diesen Code kümmern, da Sie sich sonst möglicherweise in einer schwindenden Situation befinden. Der Hauptgrund, warum ich sagen kann, dass dies auf Fehlerbehebungen und geringfügige Änderungen der Anforderungen zurückzuführen ist. Wenn ein Entwickler einige der Funktionsfälle vergisst, kann er einen Fehler beheben, indem er eine oder mehrere logische Bedingungen hinzufügt, indem er if- oder verschachtelte if-Bedingungen schreibt. Im Allgemeinen kann die zyklomatische Komplexität auf folgende Weise berechnet werden.

Zyklokmatische Komplexität = Anzahl der Entscheidungspunkte + 1 Die Entscheidungspunkte können Ihre bedingten Anweisungen sein, z. B. ob, wenn ... sonst, für die Schleife, für die Schleife usw. wechseln.

Bitte beziehen Sie sich auf das folgende Beispiel String str = "someString"; if (str.equals (case1)) etwas tun; if (str.equals (case2)) etwas tun; sonst mache Standard-Sache;

Hier ist die zyklomatische Komplexität wie folgt: Zyklomatische Komplexität = wenn für Fall1 + wenn für Fall2 + sonst + 1 = 4 Die zyklomatische Komplexität hat im Bereich der Prüfung und Wartbarkeit eine größere Bedeutung. Wenn Sie Testfälle schreiben, müssen Sie die zyklomatische Komplexität im Auge behalten. Wenn die zyklomatische Komplexität 3 beträgt, müssen Sie mindestens e gültige Testfälle schreiben. Die folgende Tabelle beschreibt den Typ der Anwendung. Zyklomatische Komplexität liegt 1 - 10  Normal zu betrachten Zyklomatische Komplexität liegt 11 - 20  Mittlere Anwendung Zyklomatische Komplexität liegt 21 - 50  Riskante Anwendung Zyklomatische Komplexität liegt mehr als 50  Instabile Anwendung Neben logischen Operatoren wie „&&“, „|| ” sind auch zusätzlich zur zyklomatischen Komplexität. Wenn Sie das Programm wie folgt schreiben: If (name.equals (name1) || name.gleich (name2) || name.equals (name3) && age! = 23) {etwas tun} Hier kann die zyklomatische Komplexität wie folgt berechnet werden: Anzahl der Entscheidungspunkte + Anzahl der logischen Operatoren + 1, was If + || + || + && + 1 = entspricht 5 Es ist auch richtig, dass dies Auswirkungen auf die Leistung der Anwendung hat. Wie auch immer Sie in einem bestimmten Design sehen mögen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltgehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.gleich (name3) && age! = 23) {etwas tun} Hier kann die zyklomatische Komplexität wie folgt berechnet werden: Anzahl der Entscheidungspunkte + Anzahl der logischen Operatoren + 1, gleich If + || + || + && + 1 = 5 It Dies gilt auch für die Leistung der Anwendung. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltergehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.gleich (name3) && age! = 23) {etwas tun} Hier kann die zyklomatische Komplexität wie folgt berechnet werden: Anzahl der Entscheidungspunkte + Anzahl der logischen Operatoren + 1, gleich If + || + || + && + 1 = 5 It Dies gilt auch für die Leistung der Anwendung. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltergehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.= 23) {etwas tun} Hier kann die zyklomatische Komplexität wie folgt berechnet werden: Anzahl der Entscheidungspunkte + Anzahl der logischen Operatoren + 1, gleich If + || + || + && + 1 = 5 Es ist auch wahr, dass dies der Fall ist Auswirkungen auf die Leistung der Anwendung. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltgehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.= 23) {etwas tun} Hier kann die zyklomatische Komplexität wie folgt berechnet werden: Anzahl der Entscheidungspunkte + Anzahl der logischen Operatoren + 1, gleich If + || + || + && + 1 = 5 Es ist auch wahr, dass dies der Fall ist Auswirkungen auf die Leistung der Anwendung. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltgehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.+1 = 5 Es ist auch richtig, dass dies Auswirkungen auf die Leistung der Anwendung hat. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltergehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.+1 = 5 Es ist auch richtig, dass dies Auswirkungen auf die Leistung der Anwendung hat. Wie auch immer Sie in einem bestimmten Design sehen, es kann mehrere Fälle geben und jeder Fall muss auf eine völlig andere Weise behandelt werden, einige Entwickler schreiben mit Factory-Design. In dieser Fabrikkonstruktion kann es entweder ein Schaltergehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.In dieser Fabrikkonstruktion kann es entweder ein Schaltgehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.In dieser Fabrikkonstruktion kann es entweder ein Schaltgehäuse oder mehrere andere Bedingungen geben. Lassen Sie mich ein Beispiel geben. Betrachten wir einen Handler, der je nach Eingabe völlig anders behandelt wird. Wenn der Fall "A" ist, sollte er auf eine bestimmte Weise behandelt werden, wenn es sich um den Fall "B" handelt, sollte er auf eine andere Weise behandelt werden. Schauen wir uns den folgenden Code an.

 Interface Handler package com.core.cc.handler; /** * @author Debadatta Mishra(PIKU) * */ public interface Handler { public void handle(); } 
Klasse AHandler
 package com.core.cc.handler; /**This class implements Handler * @author Debadatta Mishra(PIKU) * */ public class AHandler implements Handler { public void handle() { System.out.println("A handler"); } } 
Klasse BHandler
 package com.core.cc.handler; /**This class implements Handler Interface * @author Debadatta Mishra(PIKU) * */ public class BHandler implements Handler { public void handle() { System.out.println("B handler"); } } 
Klasse AbstractHandler
 package com.core.cc.handler; /**This class is used as a Factory class. * @author Debadatta Mishra(PIKU) * */ public class AbstractHandler { /**This is a very traditional method, you * can obtain the dynamic object by using * several if conditions. * @param handlerName * @return an object of type {@link Handler} */ public static Handler getHandler( String handlerName ) { Handler handler = null; try { if( handlerName.equals("A")) handler = new AHandler(); if( handlerName.equals("B") ) handler = new BHandler(); } catch( Exception e ) { System.out.println("There is no specific handler"); } return handler; } } 
Klasse TestDynamicHandler
 import com.core.cc.handler.AbstractHandler; import com.core.cc.handler.Handler; /**This is a testharness class. * @author Debadatta Mishra(PIKU) * */ public class TestDynamicHandler { public static void main(String[] args) { Handler handler = AbstractHandler.getHandler("B"); handler.handle(); } } 

In den obigen Beispielen ist das Schreiben des Codes nicht falsch, aber der Compiler kann einige Zeit dauern, wenn Ihre Fälle zunehmen. Für jeden neuen Fall müssen Sie eine neue Klasse schreiben und eine oder mehrere if-Klauseln in der Klasse „AbstractHandler“ hinzufügen. Sie können die Klasse "AbstractHandler" folgendermaßen ändern, sodass sie sehr komplex aussieht und die Klasse "AbstractHandler" nicht aktualisiert werden muss.

 package com.core.cc.handler; /**This class is used as a Factory class. * @author Debadatta Mishra(PIKU) * */ public class AbstractHandler { /**This method is used to obtain the dynamic * object of the type Handler * @param handlerName * @return an object of type {@link Handler} */ public static Handler getHandler( String handlerName ) { Handler handler = null; try { handler = (Handler) Class.forName( "com.core.cc.handler." + handlerName + "Handler") .newInstance(); } catch( Exception e ) { System.out.println("There is no specific handler"); } return handler; } } 

Der obige Code vereinfacht Ihre Programmierung und bietet die Flexibilität, Ihre Fälle hinzuzufügen, ohne größere Änderungen vorzunehmen. Immerhin ist dies die Schönheit des Java Factory Design. In diesem Zusammenhang können Sie argumentieren, dass die Reflexion vom Standpunkt der Leistung aus langsamer ist. Ich kann sagen, dass sie im Vergleich zu vielen if… else-Klauseln schneller sein wird. Es gibt jedoch mehrere Möglichkeiten, wie Sie schönen Code schreiben können, um eine große zyklomatische Komplexität zu vermeiden.

Fazit

Ich hoffe, dass Ihnen mein Artikel gefällt. Wenn Sie Probleme oder Fehler finden, senden Sie mir bitte eine E-Mail an die Adresse

[email protected]

. Dieser Artikel ist nur für diejenigen gedacht, die neu in der Java-Entwicklung sind. Dieser Artikel hat keine kommerzielle Bedeutung. Bitte geben Sie mir das Feedback zu diesem Artikel.

Diese Geschichte "Umgang mit zyklomatischer Komplexität in Java-Code" wurde ursprünglich von JavaWorld veröffentlicht.