Hay muchas respuestas en mi pregunta anterior sobre la simplicidad relacionada con la legibilidad que me ayudaron a ver que mi definición y comprensión de la simplicidad en el código era, posiblemente, incorrecta.
¿Cómo puedo definir la simplicidad en el código? ¿Qué medidas y métricas de software están disponibles para medir la simplicidad del código?
code-quality
Ricardo
fuente
fuente
Respuestas:
Las métricas más comunes para medir la complejidad (o simplicidad, si considera que la simplicidad es lo opuesto a la complejidad) son la Complejidad Ciclomática de McCabe y las Métricas de Complejidad de Halstead .
La complejidad ciclomática mide el número de rutas distintas a través de una unidad dada, generalmente un método o función, aunque también se puede calcular en una clase. A medida que aumenta el número de rutas, se hace más difícil recordar el flujo de datos a través de un módulo dado, que está relacionado con el concepto de memoria de trabajo . La alta complejidad ciclomática tiende a indicar dificultad en la capacidad de probar un módulo; se requieren más casos de prueba para cubrir las diversas rutas a través del sistema. También se han realizado estudios que han relacionado la alta complejidad ciclomática con las altas tasas de defectos. Típicamente, una complejidad ciclomática de 10 indica que una unidad debe ser revisada y posiblemente refactorizada.
Las medidas de complejidad de Halstead utilizan las entradas de operadores y operandos totales y distintos para calcular el volumen, la dificultad y el esfuerzo de un fragmento de código. La dificultad, que es el (número de operadores únicos / 2) * (número total de operandos / número de operandos únicos), está ligada a la capacidad de leer y comprender el código para tareas tales como aprender el sistema o realizar una revisión del código. Nuevamente, puede contar esto en un nivel de sistema, un nivel de clase o un nivel de método / función. Hay algunas publicaciones sobre cómo calcular estas medidas aquí y aquí .
Simplemente contar líneas de código también puede darle una idea de la complejidad. Más líneas de código significa que hay más para leer y comprender en un módulo. Dudaría en usar esto como una medida independiente. En cambio, lo usaría con otras mediciones, como el número de defectos en un módulo dado para obtener la densidad de defectos. Una alta densidad de defectos podría indicar problemas al escribir pruebas y realizar revisiones de código, que pueden o no ser causadas por código complejo.
Fan-in y fan-out son otras dos métricas relacionadas con el flujo de datos. Como se define aquí , fan in es la suma de los procedimientos llamados, los parámetros leídos y las variables globales leídas y desplegadas es la suma de los procedimientos que llaman a un procedimiento dado, los parámetros escritos (expuestos a usuarios externos, pasados por referencia), y variables globales escritas en. Nuevamente, un alto nivel de entrada y salida puede ser indicativo de un módulo que puede ser difícil de entender.
En paradigmas específicos, puede haber otras medidas o métricas que también sean útiles. Por ejemplo, en el mundo orientado a objetos, la monitorización del acoplamiento (deseo bajo), la cohesión (deseo alto) y la profundidad de la herencia (deseo bajo) se pueden usar para evaluar qué tan simple o complicado es un sistema.
Por supuesto, es importante darse cuenta de que muchas medidas y métricas son simplemente indicadores. Debe usar su criterio para determinar si es necesario refactorizar para aumentar la simplicidad o si no vale la pena hacerlo. Puede realizar las mediciones, calcular las métricas y conocer su código, pero no desea diseñar su sistema por los números. En definitiva, haz lo que tenga sentido.
fuente
En lugar de mirar un modo formal de definir la simplicidad, preferiría definir la simplicidad como un atributo de calidad de escritura de código.
No estoy poniendo algo de simplicidad, pero ¿cuándo llamas a algo simple o no?
1. Código transversal:
¿Qué tan fácil es navegar por el código? ¿Es fácil detectar dónde se escriben las funciones de la API? ¿Es fácil entender los flujos de llamadas, por ejemplo, qué métodos están llamando a otros (y por qué)? ¿Hay buenas máquinas de estado implementadas o algoritmos claramente identificados?
Cuando el recorrido del código es fácil, el código es simple de seguir.
2.
Nombramiento Mientras que otros estándares de codificación ayudan a que el código se vea más limpio, lo más importante es nombrar clases / instancias de objetos / Variables / métodos. El uso de nombres claros e inequívocos claramente tiene un gran impacto en la simplicidad del código. Cuando es difícil identificar un nombre simple, es una señal de que tal vez quiera repensar la idea de esa variable / método.
3. Interpretación y referencias
¿Tiene cada uno de sus métodos un papel claro que desempeñar? ¿Cada variable / atributo es fácil de determinar el papel que están jugando? Cuando un código hace algo que implica suposiciones o afecta a un conjunto de variables no relacionadas, puede convertirse en una pesadilla de mantenimiento.
4. Dependencia o acoplamiento
Esto es difícil de juzgar con solo mirar el código, pero se vuelve muy evidente si alguien intenta corregir sus errores. Cuando otras cosas cambian en algún otro objeto, ¿cambia la operación aquí? ¿Son obvios esos cambios? ¿Necesita cambiar la API con tanta frecuencia para acomodar cosas? Esto sugiere que las relaciones entre módulos no son simples
5. Entradas de usuario o aplicaciones
Finalmente, ¿qué tan simples son las entradas de usuario o aplicaciones aceptadas en la API / UI? Cuando múltiples usuarios / aplicaciones posibles (para diferentes propósitos) necesitan darle, ¿son obvios? ¿Hay estados / detalles que no están relacionados con la abstracción superior pero que aún van y vienen de la interfaz?
Una pregunta simple que generalmente haría es la siguiente: si en lugar de un programa, si hubiera pedido que un humano realizara la misma función, ¿habría llenado esta información en un formulario en papel ? Si no, no soy lo suficientemente simple aquí.
No diré que esta lista es exhaustiva, pero supongo que el criterio es cuán fácil o difícil es usar y modificar el software. Eso es simple
fuente
No conozco ninguna buena métrica existente para la simplicidad del código (no significa que no existan, solo que no las conozco). Podría proponer algunos, tal vez algunos ayuden:
Simplicidad de las características del lenguaje utilizadas: si el lenguaje tiene características que podrían considerarse "avanzadas" y "simples", podría contar el número de ocurrencias de las características avanzadas. La forma de definir "avanzado" podría ser un poco más subjetiva. Supongo que algunos podrían decir que esto también es como medir la "inteligencia" de un programa. Un ejemplo común: algunos podrían decir que el
?:
operador debería ser una función "avanzada", otros podrían estar en desacuerdo. No sé lo fácil que sería escribir una herramienta que pueda probar esto.Simplicidad de construcciones dentro del programa: puede medir el número de parámetros que aceptará una función. Si usted tiene> n % de todas las funciones con> m parámetros, se puede optar por contar como no simple, dependiendo de cómo se defina n y m (tal vez n = 3 ym = 6?). Creo que hay algunas herramientas de análisis estático que pueden medir esto; creo que JTest simplemente midió funciones con parámetros > m .
Podría intentar contar el número de bucles anidados o estructuras de control. Esto creo que en realidad no es una mala métrica y creo que hay un nombre para ello (no puedo recordar la parte superior de mi cabeza). Nuevamente, creo que hay herramientas (de nuevo, como JTest) que pueden medir esto, hasta cierto punto.
Podrías intentar medir la "refactorabilidad". Si su código contiene muchas piezas de código que podrían ser refactorizadas pero no lo son , tal vez eso podría no ser simple. También recuerdo desde el momento en que trabajé con JTest que también intentó medir esto, pero recuerdo que a menudo no estaba de acuerdo con eso en este caso, así que YMMV.
Podría intentar medir el número de capas entre diferentes partes de su sistema. Por ejemplo: ¿cuántos códigos diferentes tocarán los datos que provienen de un formulario web antes de que se almacenen en la base de datos? Esto podría ser complicado de medir correctamente ...
fuente
?:
son un problema cuando están anidadas a 5 de profundidad. En cuanto a las capas, las capas separadas limpiamente son mejores que una capa enrevesada. Pero 7 capas en su mayoría redundantes, cuando solo 2 o 3 eran necesarias, es algo malo.