Gracias a una pregunta en Code Review , tuve un pequeño desacuerdo (que esencialmente es una oportunidad para aprender algo) sobre qué es exactamente la Complejidad Ciclomática para el siguiente código.
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");
}
Al escribir este código en Eclipse y usar el complemento de métricas Eclipse , me dice que la Complejidad Ciclomática McCabe para el método principal es 2, y para el thro
método dice 2.
Sin embargo, alguien más me dice que la complejidad de llamar thro
varias veces es number of calls * method complexity
y, por lo tanto, afirma que la complejidad del método principal es 7 * 2 = 14.
¿Estamos midiendo cosas diferentes? ¿Podemos los dos estar en lo correcto? ¿O cuál es la complejidad ciclomática real aquí?
metrics
cyclomatic-complexity
Simon Forsberg
fuente
fuente
Respuestas:
Cuando entendí esto correctamente, la Complejidad Ciclomática de
main
es 8, que es el número de caminos linealmente independientes a través del código. O obtienes una excepción en una de las siete líneas, o ninguna, pero nunca más de una. Cada uno de esos posibles "puntos de excepción" corresponde exactamente a una ruta diferente a través del código.Supongo que cuando McCabe inventó esa métrica, no tenía lenguajes de programación con el manejo de excepciones en mente.
fuente
main
método?Siendo 'el otro tipo', responderé aquí, y seré preciso sobre lo que digo (con lo que no fui particularmente preciso con respecto a otros formularios).
Usando el ejemplo de código anterior, calculo la complejidad ciclomática como 8, y tengo comentarios en el código para mostrar cómo calculo eso. Para describir las rutas, consideraré un bucle exitoso a través de todas las
thro()
llamadas como la ruta de código 'principal' (o 'CP = 1'):Entonces, cuento 8 rutas de código en este método principal, que para mí es una Complejidad Ciclomática de 8.
En términos de Java, cada mecanismo para salir de una función cuenta para su complejidad, por lo tanto, un método que tiene un estado de éxito y, por ejemplo, arroja, posiblemente, hasta 3 excepciones, tiene 4 rutas de salida documentadas.
La complejidad de un método que llama a tal función es:
Creo que otras cosas a considerar es que, en mi opinión, la
catch
cláusula no contribuye a la complejidad del método,catch
es simplemente el objetivo de unathrows
rama y, por lo tanto, un bloque de captura que es el objetivo de múltiplesthrow
conteos 1 vez para cada unothrow
, y no solo una vez para todo.fuente
catch (Throwable t) {...
, supongo que no importa cuántas excepciones declare lanzar.