Trattare la complessità ciclomatica nel codice Java

Trattare la complessità ciclomatica nel codice Java Debadatta Mishra IntroduzionePotresti aver sentito il termine gestione del codice in java. Si riferisce a come gestire il codice sorgente in modo che possa essere più facile in una certa misura gestirlo al momento della manutenzione. È sempre vero che i requisiti cambiano di volta in volta e il codice sorgente subisce un cambiamento in una certa misura. Potresti aver visto un modulo particolare che sembra molto rischioso da toccare. Alcune persone dicono che questo modulo funziona bene ma il codice non è gestibile. Succede nella maggior parte del settore IT, ci possono essere diversi motivi. Tuttavia posso dire che scrivere codice è un'arte. Alcuni sviluppatori prendono la questione molto seriamente. Potresti trovare l'occasione per la revisione del codice e il controllo del codice nell'organizzazione. Come scrivere il codice migliore va oltre lo scopo di questo articolo.In questo articolo vorrei concentrarmi sulla complessità ciclomatica che è molto più prevalente nel codice sorgente. È anche vero che puoi tenerti lontano da questo concetto. La nota fondamentale è come affrontare la complessità del codice.

Tecnicità

La complessità ciclomatica è un concetto sulla metrica che è stato coniato da Thomas McCabe. Fornisce la nozione di complessità strutturale di un metodo o di un codice sorgente. Fondamentalmente si occupa dei vari casi decisionali e condizionali. Se stai scrivendo un pezzo di codice che include diverse decisioni e condizioni logiche, devi prenderti cura di quel pezzo di codice altrimenti potresti trovarti in condizioni di diminuzione. Il motivo principale per cui posso dire che accade a causa della correzione di bug e di alcune piccole modifiche ai requisiti. Se uno sviluppatore dimentica alcuni dei casi funzionali, può correggere un bug aggiungendo una o più condizioni logiche scrivendo if o annidate if. Generalmente la complessità ciclomatica può essere calcolata nei seguenti modi.

Complessità ciclocmatica = Numero di punti decisionali + 1 I punti decisionali possono essere le tue affermazioni condizionali come if, if ... else, switch, for loop, while loop ecc.

Fare riferimento al seguente esempio String str = "someString"; if (str.equals (case1)) fa qualcosa; if (str.equals (case2)) fa qualcosa; altrimenti fa cosa predefinita;

Qui la complessità ciclomatica sarà la seguente Complessità ciclomatica = se per caso1 + se per caso2 + else + 1 = 4 La complessità ciclomatica ha più significato nel campo del test e della manutenibilità. Se stai scrivendo casi di test, devi tenere d'occhio la complessità ciclomatica. Se la complessità ciclomatica è 3, devi scrivere almeno un test case valido. La seguente tabella descrive il tipo di applicazione. La complessità ciclomatica è 1 - 10  Da considerare Applicazione normale La complessità ciclomatica è 11 - 20  Applicazione moderata La complessità ciclomatica è 21 - 50  Applicazione rischiosa La complessità ciclomatica è maggiore di 50  Applicazione instabile Oltre a operatori logici come "&&", "|| " sono anche un'aggiunta alla complessità ciclomatica. Se stai scrivendo il programma come il seguente If (name.equals (name1) || name.è uguale a (nome2) || name.equals (name3) && age! = 23) {do something} Qui la complessità ciclomatica può essere calcolata come segue Numero di punti decione + numero di operatori logici + 1 che è uguale a If + || + || + && + 1 = 5 È anche vero che avrà un impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.equals (name3) && age! = 23) {do something} Qui la complessità ciclomatica può essere calcolata come segue Numero di punti decione + numero di operatori logici + 1 che è uguale a If + || + || + && + 1 = 5 It è anche vero che avrà un impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.equals (name3) && age! = 23) {do something} Qui la complessità ciclomatica può essere calcolata come segue Numero di punti decione + numero di operatori logici + 1 che è uguale a If + || + || + && + 1 = 5 It è anche vero che avrà un impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.= 23) {fare qualcosa} Qui la complessità ciclomatica può essere calcolata come segue Numero di punti decione + numero di operatori logici + 1 che è uguale a If + || + || + && + 1 = 5 È anche vero che avrà impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.= 23) {fare qualcosa} Qui la complessità ciclomatica può essere calcolata come segue Numero di punti decione + numero di operatori logici + 1 che è uguale a If + || + || + && + 1 = 5 È anche vero che avrà impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.+1 = 5 È anche vero che avrà un impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.+1 = 5 È anche vero che avrà un impatto sulle prestazioni dell'applicazione. Comunque tu possa vedere in un certo design, potrebbero esserci diversi casi e ogni caso deve essere gestito in un modo completamente diverso, alcuni sviluppatori scrivono usando il design di fabbrica. In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un Handler che gestisce completamente differenti in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un Handler che gestisce completamente differenti in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.In quel progetto di fabbrica possono esserci o il caso dell'interruttore o diverse condizioni. Faccio un esempio. Consideriamo un gestore che gestisce completamente diversi in base all'input. Se il caso è "A" dovrebbe essere gestito in un modo particolare, se è il caso "B", dovrebbe essere gestito in un altro modo. Esaminiamo il seguente pezzo di codice.

 Interface Handler package com.core.cc.handler; /** * @author Debadatta Mishra(PIKU) * */ public interface Handler { public void handle(); } 
Classe 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"); } } 
Classe 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"); } } 
classe 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; } } 
class 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(); } } 

Negli esempi precedenti, non c'è niente di sbagliato nello scrivere il codice this, ma il compilatore potrebbe impiegare del tempo quando i tuoi casi aumentano. Per ogni nuovo caso, devi scrivere una nuova classe e devi aggiungere una o più clausole if nella classe “AbstractHandler”. È possibile modificare la classe "AbstractHandler" nel modo seguente in modo che appaia molto sofisticata e quindi non è necessario aggiornare la classe "AbstractHandler".

 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; } } 

Il codice precedente semplifica la programmazione e offre la flessibilità di aggiungere i casi senza apportare modifiche importanti. Dopo tutto questo è il bello del Java Factory Design. A questo proposito si può sostenere che, la riflessione è più lenta dal punto di vista della prestazione, posso dire che sarà più veloce rispetto a molte clausole if… else. Tuttavia ci sono diversi modi per scrivere codice stupendo per evitare una grande complessità ciclomatica.

Conclusione

Spero che il mio articolo ti piaccia. In caso di problemi o errori, non esitare a inviarmi una mail all'indirizzo

[email protected]

. Questo articolo è destinato solo a coloro che sono nuovi allo sviluppo di Java. Questo articolo non ha alcun significato commerciale. Forniscimi il feedback su questo articolo.

Questa storia, "Trattare la complessità ciclomatica in codice Java" è stata originariamente pubblicata da JavaWorld.