¿Los métodos iterativos como los que se encuentran comúnmente en lenguajes modernos como C #, JavaScript y (con suerte) en Java 8 reducen el impacto de la complejidad ciclomática en la comprensibilidad y compatibilidad del código?
Por ejemplo, en C # podríamos tener el siguiente código:
List<String> filteredList = new List<String>();
foreach (String s in originalList){
if (matches(s)){
filteredList.add(s);
}
}
Esto tiene una complejidad ciclomática simple de 2.
Podríamos reescribir esto fácilmente como:
List<String> filteredList = originalList.where(s => matches(s));
Que tiene una complejidad ciclomática simple de 0.
¿Esto realmente da como resultado un código más compatible? ¿Hay alguna investigación real sobre este tema?
cyclomatic-complexity
Cruzar
fuente
fuente
Respuestas:
Supongo que acabas de dividir / mover la complejidad. Disminuyó porque no cuenta la implementación de
.where()
en su CC.El CC general no se ha movido realmente, el CC de su propio código disminuyó, solo porque ahora se ha movido al código del marco.
Yo diría que es más fácil de mantener. Cuando es una característica del lenguaje, úselo. No es un "ohh, ya veo, es un truco inteligente" lo que estás usando, solo una simple función de reducción en línea.
fuente
Todo lo que está haciendo es resaltar una falla en la complejidad ciclomática como una métrica, la complejidad del código realmente no ha cambiado. Tiene una rama explícita en el primer ejemplo y necesita comprender que hay una rama implícita en el segundo. El segundo es más claro y fácil de entender siempre que comprenda la sintaxis, y dado que utiliza una sintaxis menos básica, puede ser un problema.
fuente
where
aquí es probable que provenga de un marco. Creo que la complejidad ciclomática como métrica es útil incluso aquí porque, si bien dividir una función en varias no disminuye la complejidad general del sistema (de hecho, a menudo la aumenta, aunque solo sea un poco), te ayuda a determinar cuándo Una parte del sistema se vuelve demasiado compleja y necesita ser desglosada.Para responder la pregunta objetivamente, necesitaríamos algún tipo de métrica para la mantenibilidad. La complejidad ciclomática en sí misma no es una medida de mantenibilidad, pero es un componente de algunas métricas que pretenden medir la mantenibilidad. Por ejemplo, la fórmula para el índice de mantenimiento es:
¿Dónde
G
está la complejidad ciclomática del código en cuestión? Por lo tanto, la reducción de la complejidad ciclomática de un código mejora, por definición, el índice de mantenimiento del código y otras métricas que utilizan de manera similar la complejidad ciclomática .Es difícil decir si el tipo de cambio que propone hace que el programa parezca más fácil de mantener para los programadores; eso probablemente depende de qué tan familiarizados estén (en su caso) con el
where
método.fuente
(>_<)
Debido a que se ha demostrado que la complejidad ciclomática (CC) está fuertemente correlacionada con el tamaño del código, "tanto que se puede decir que CC no tiene absolutamente ningún poder explicativo propio". lo que realmente se pregunta es si "los métodos iterativos como los que se encuentran comúnmente en lenguajes modernos como C #, JavaScript y (con suerte) en Java 8 reducen el impacto del tamaño del código en la comprensibilidad y compatibilidad del código".
En ese punto, uno esperaría que la respuesta fuera obvia. Se sabe desde hace décadas que un código más corto es generalmente más fácil de entender, mantener y soportar.
fuente
Si está hablando de la estadística bruta de la complejidad ciclomática, seguro. Acaba de disparar de 2 a 0. Si va por números, ganancia pura, hasta el final.
Sin embargo, desde una perspectiva práctica (léase: humana), diría que en realidad has aumentado la complejidad en 2. Un punto de eso proviene del hecho de que ahora algún otro programador debe traer u obtener conocimiento de LINQ de sintaxis fluida para comprender esto. código.
Otro punto de mayor dificultad proviene de comprender las expresiones Lambda; Aunque un Lambda es bastante sencillo en este caso , hay algunos cambios de paradigma que deben hacerse para apreciarlos completamente.
Este caso, el uso
a.where(x => matches(x, arg))
no es terrible, y para ser sincero, es una excelente manera de hacer que un compañero de trabajo vea y trabaje con expresiones LINQ y Lambda por primera vez (en realidad presenté un tutorial sobre LINQ / Lambdas a algunos ex compañeros de trabajo que usan esto y otros conjuntos de código, con gran efecto.) Sin embargo, el uso de estos requiere cierto conocimiento.Recomiendo precaución, porque he visto casos en los que el refactorizador LINQ en realidad es significativamente peor de leer de lo que se
foreach
convierte ese ciclo.fuente
Subjetivamente, depende de la audiencia del desarrollador, si entienden las expresiones lambda, entonces;
es más rápido de entender y quizás un poco más fácil. Me preocuparía más el uso de s, y coincidencias (). Tampoco es autodescriptivo, algo así como;
O
le da al desarrollador información más significativa y es más fácil de analizar, sin tener que sumergirse en la función coincidencias () para determinar qué coincidencia se está realizando.
La capacidad de mantenimiento no solo se trata de la capacidad de comprender el código, sino principalmente de la velocidad y precisión con la que se puede comprender el código.
fuente