Establecimiento de métricas del índice de mantenibilidad

Establecimiento de métricas de índice de mantenibilidad para aplicaciones COBOL

El Índice de Mantenibilidad (IM) es una de las métricas compuestas más utilizadas para medir la calidad del software. Condensa tres propiedades estructurales del código (tamaño, complejidad y volumen) en una única puntuación numérica que predice la dificultad de modificarlo. Para los lenguajes modernos, la fórmula, los umbrales y las herramientas están bien establecidos. En el caso de COBOL, la situación es más compleja, y la mayoría de los equipos aplican la fórmula genérica sin ajustes o abandonan por completo la medición cuantitativa, ya que las puntuaciones no parecen corresponderse con la experiencia real de los desarrolladores.

Ambos enfoques producen resultados engañosos. Aplicar la fórmula estándar de MI a COBOL sin comprender cómo se comportan sus componentes en el contexto sintáctico de COBOL genera puntuaciones sistemáticamente sesgadas, haciendo que los programas de alta calidad parezcan marginales y los de baja calidad, aceptables. Abandonar por completo la medición deja las decisiones de modernización sin la base cuantitativa necesaria para ser defendibles ante las partes interesadas del negocio y para priorizar las acciones correctivas en una cartera de miles de programas.

Obtenga una visión completa de las métricas de COBOL.

SMART TS XL Clasifica simultáneamente todos los programas COBOL según su complejidad, el número de entradas (fan-in) y la profundidad de las dependencias JCL.

MÁS INFORMACIÓN

El camino correcto consiste en comprender qué mide específicamente la fórmula MI en COBOL, dónde subestima y sobreestima la calidad, qué métricas complementarias corrigen sus limitaciones específicas de COBOL y cómo calibrar los umbrales en función de su cartera real, en lugar de utilizar parámetros genéricos derivados de bases de código de lenguajes modernos. Esta guía abarca estos cuatro aspectos, con la profundidad técnica suficiente para implementar un programa COBOL MI y la orientación práctica necesaria para utilizarlo en la toma de decisiones de modernización.

Un último punto antes de entrar en los detalles técnicos: el Índice de Mantenibilidad busca ofrecer una visión integral de la carga de mantenimiento relativa para las diferentes secciones de un proyecto, combinando diversas métricas. Esta visión integral es valiosa para los portafolios de COBOL precisamente porque ninguna métrica por sí sola abarca la totalidad del panorama. El Índice de Mantenibilidad es el punto de partida, no la historia completa, pero sí el lugar adecuado para comenzar.

Por qué la medición de la mantenibilidad es más importante para COBOL que para los lenguajes modernos.

Medir la mantenibilidad de un código Java o Python con dos años de antigüedad, bien probado y mantenido por el equipo que lo escribió, proporciona información útil, pero rara vez es urgente. El código es legible para sus autores. La lógica está documentada o se puede derivar de las pruebas. El costo de los cambios está limitado por la familiaridad del equipo con el código.

Las carteras de productos COBOL en industrias reguladas difieren en tres aspectos que hacen que la medición cuantitativa de la mantenibilidad no sea una práctica de calidad, sino una necesidad operativa.

La brecha de conocimiento. La mayor parte del código COBOL contiene lógica de negocio nunca documentada formalmente. Los procesos por lotes escritos hace décadas codifican reglas que nadie recuerda. Los desarrolladores que pueden leer el código con fluidez y estimar con precisión el costo de los cambios se están jubilando. Los desarrolladores que permanecen tienen un conocimiento parcial de partes del portafolio. Sin métricas cuantitativas, la estimación del costo de los cambios depende completamente del desarrollador al que se le pregunte, y la variabilidad en esas estimaciones es lo suficientemente alta como para que la planificación del proyecto sea poco confiable.

El problema de la escala. Un portafolio típico de COBOL contiene miles de programas, muchos de los cuales no se han modificado en años. Ningún equipo puede evaluar manualmente miles de programas antes de que comience un programa de modernización. Las métricas que se pueden calcular automáticamente en todo el portafolio en cuestión de horas reemplazan semanas de revisión manual.

El requisito del caso de negocio. Los programas de modernización requieren una justificación de la inversión. Los ejecutivos que aprueban presupuestos de modernización multimillonarios buscan evidencia cuantitativa que justifique la inversión. Las puntuaciones de MI, los índices de deuda técnica derivados de MI y las estimaciones de costos de cambio que toman como referencia los umbrales de MI proporcionan dicha evidencia en un formato que puede presentarse a las partes interesadas no técnicas.

La fórmula MI y sus componentes específicos de COBOL.

La fórmula más utilizada para calcular el Índice de Mantenibilidad es:

MI = 171 - 5.2 × ln(Halstead Volume) - 0.23 × (Cyclomatic Complexity) - 16.2 × ln(Lines of Code)

La variante acotada de Microsoft, utilizada por la mayoría de las herramientas comerciales, la relaciona con una escala de 0 a 100:

MI (bounded) = max(0, (171 - 5.2 × ln(HV) - 0.23 × CC - 16.2 × ln(LOC)) × 100 / 171)

Cada componente tiene consideraciones específicas relevantes para COBOL.

Líneas de código en COBOL

Los archivos fuente de COBOL contienen cuatro divisiones: IDENTIFICACIÓN, ENTORNO, DATOS y PROCEDIMIENTO. La DIVISIÓN IDENTIFICACIÓN identifica el programa. La DIVISIÓN ENTORNO describe su entorno de ejecución. La DIVISIÓN DATOS define sus estructuras de datos. Solo la DIVISIÓN PROCEDIMIENTO contiene instrucciones ejecutables.

La cuestión de la medición: ¿debería LOC contabilizar todas las líneas de las cuatro divisiones o solo las declaraciones de PROCEDURE DIVISION?

Para fines de MI, contar todas las líneas (incluidas las declaraciones de datos) aumenta significativamente el número de líneas de código (LOC) sin un aumento correspondiente en la complejidad de ejecución. Un programa COBOL con 400 líneas de DATA DIVISION que definen la disposición de los registros y una PROCEDURE DIVISION de 100 líneas tiene características de mantenibilidad diferentes a las de un programa con 100 líneas de DATA DIVISION y una PROCEDURE DIVISION de 400 líneas, pero el conteo de líneas de código sin procesar los trata de forma idéntica.

Buenas prácticas: Para el cálculo de MI en COBOL, utilice el recuento de sentencias de PROCEDURE DIVISION (excluyendo líneas en blanco, líneas de comentarios y encabezados de división/sección/párrafo) en lugar del total de líneas del código fuente. Esto produce valores de LOC que se corresponden mejor con la complejidad del ejecutable.

El problema de los miembros de COPY: Las instrucciones COPY incluyen miembros externos del código fuente en tiempo de compilación. Una instrucción COPY que se expande a 200 líneas de definiciones de datos aporta una línea al archivo fuente, pero 200 líneas al programa compilado. Algunas herramientas cuentan las líneas lógicas de código fuente (expansión posterior a la copia); otras cuentan las líneas físicas del código fuente. La diferencia puede ser de un orden de magnitud para programas con un uso intensivo de COPY.

Atención: Si su herramienta de gestión de información (MI) contabiliza las líneas de código fuente físicas, los programas con un uso intensivo de COPY parecerán más pequeños y fáciles de mantener de lo que realmente son. Compruebe siempre si la expansión de LOC en su herramienta es anterior o posterior a la copia.

Complejidad ciclomática en COBOL

La complejidad ciclomática es una métrica de calidad del código que mide la comprensibilidad y el mantenimiento del código al medir el número de rutas independientes a través de ese código. En COBOL, las estructuras de decisión que crean rutas independientes incluyen:

Construcción COBOLImpacto de la complejidad ciclomática
IF ... END-IF+1 por IF
IF ... ELSE ... END-IF+1 por IF (ELSE no agrega otra ruta)
EVALUATE ... WHEN+1 por cláusula WHEN
PERFORM UNTIL condition+1 por condición HASTA
PERFORM VARYING ... WITH TEST BEFORE/AFTER+1 por VARIABLE
AT END cláusula sobre LEER+1
ON EXCEPTION / NOT ON EXCEPTION+1 por cada controlador de excepciones
ON OVERFLOW / NOT ON OVERFLOW+1 por cada controlador de desbordamiento
ON SIZE ERROR+1 por controlador de errores de tamaño

El punto ciego de nivel 88: Los nombres de las condiciones de nivel 88 de COBOL crean condiciones lógicas que aparecen en las sentencias IF y EVALUATE, pero que se definen en la DIVISIÓN DE DATOS. Un programa con veinte condiciones de nivel 88, cada una referenciada en múltiples estructuras de decisión, tiene una complejidad de comportamiento significativamente mayor de la que sugiere el recuento de sentencias de la DIVISIÓN DE PROCEDIMIENTOS. La Complejidad Ciclomática cuenta los puntos de decisión, pero no puede capturar las relaciones semánticas entre los nombres de nivel 88 y la lógica que los evalúa.

REALIZAR MEDIANTE complejidad implícita: PERFORM SECTION-A THRU SECTION-Z ejecuta todos los párrafos entre la SECCIÓN-A y la SECCIÓN-Z. El número de párrafos y las estructuras de decisión dentro de ellos son parte de la complejidad efectiva de la instrucción PERFORM, pero CC calculado a nivel de instrucción trata PERFORM THRU como un único camino, independientemente de lo que haya en medio.

Volumen de Halstead en COBOL

El volumen de Halstead es una medida del tamaño y la complejidad del programa basada en el número de operadores y operandos. En COBOL:

Los operadores son verbos y palabras clave de COBOL: MOVE, ADD, SUBTRACT, MULTIPLY, DIVIDE, COMPUTE, IF, PERFORM, READ, WRITE, OPEN, CLOSE, CALL, GO TO, EVALUATE, WHEN, etc.

Los operandos son nombres de datos, literales y constantes figurativas: elementos de datos definidos en la DIVISIÓN DE DATOS, literales numéricos y de cadena, y constantes figurativas de COBOL (ESPACIOS, CEROS, VALORES ALTOS, VALORES BAJOS).

El factor verbosidad: COBOL es significativamente más verboso que los lenguajes modernos para una lógica equivalente. Una expresión de Java total = quantity * unitPrice * (1 - discount) es una línea con cuatro operadores y cuatro operandos. El equivalente en COBOL:

cobol

       COMPUTE WS-TOTAL = WS-QUANTITY * WS-UNIT-PRICE
                        * (1 - WS-DISCOUNT)

Esto es aproximadamente equivalente en operadores y operandos, pero consideremos un cálculo más complejo que en Java podría usar tres líneas. En COBOL, podría requerir cinco o más líneas debido a la falta de encadenamiento de expresiones y la necesidad de usar campos de almacenamiento intermedios. El volumen de Halstead será correspondientemente mayor para COBOL que para su equivalente en Java, simplemente porque COBOL expresa el mismo cálculo con más tokens de lenguaje.

La consecuencia práctica es que los programas COBOL tendrán volúmenes de Halstead más altos que los programas en lenguajes modernos con lógica equivalente. Un mayor volumen de Halstead reduce la MI. Por lo tanto, los programas COBOL obtendrán sistemáticamente puntuaciones más bajas en MI que los programas en lenguajes modernos de complejidad equivalente, no porque sean más difíciles de mantener, sino porque COBOL es sintácticamente más verboso.

Dónde se queda corta la MI estándar para COBOL: Cuatro puntos ciegos

Aun calculándose correctamente, la fórmula estándar de MI omite cuatro dimensiones de la mantenibilidad de COBOL que tienen un impacto significativo en el costo real de los cambios.

1. COPIA Acoplamiento de miembros

Un copybook COBOL incluido en 300 programas constituye una dependencia de mantenimiento que afecta a los 300 programas ante cualquier modificación. Este acoplamiento no aparece en ningún componente de la fórmula MI. Un programa que incluye veinte copybooks tiene 300 dependencias implícitas que MI trata como equivalentes a un programa sin copybooks.

Métrica complementaria: Recuento de dependencias de miembros de copia, que indica el número de sentencias COPY únicas en la DIVISIÓN DE DATOS de un programa. Los programas con un alto acoplamiento de COPY requieren un análisis de impacto antes de cualquier cambio para comprender qué otros programas comparten las mismas definiciones de copybook.

2. Fan-In (Llamado por conteo)

Un subprograma COBOL llamado por otros 150 programas representa un riesgo de modificación elevado, independientemente de su puntuación MI. Un subprograma de fácil mantenimiento (MI = 85) llamado por 150 programas es más difícil de modificar de forma segura que una utilidad de difícil mantenimiento (MI = 45) llamada por ningún programa. La fórmula MI no tiene en cuenta la frecuencia de uso de un programa.

Métrica complementaria: Fan-in, que indica el número de programas distintos que llaman a un programa determinado mediante CALL o despacho dinámico. El Fan-in es el principal factor determinante del riesgo de cambio para los subprogramas, independientemente de su complejidad interna.

3. Profundidad de dependencia de JCL

Un programa COBOL invocado por un trabajo JCL que tiene quince trabajos dependientes posteriores (trabajos que se ejecutan después y dependen de su resultado) conlleva un riesgo operativo que está completamente fuera del alcance de MI. Un programa con MI = 55 que se ejecuta de forma independiente es menos arriesgado de modificar que un programa con MI = 80 que se encuentra en el centro de una compleja cadena de dependencias por lotes.

Métrica complementaria: Profundidad de dependencia de JCL, que indica la profundidad de la cadena de dependencias descendentes en la red de trabajos de JCL. Los programas con una alta profundidad de dependencia de JCL requieren un alcance de prueba más amplio para cualquier cambio, independientemente de su puntuación MI interna.

4. Inflación de código muerto

Los párrafos y secciones obsoletos, el código COBOL definido pero nunca ejecutado, aumentan el número de líneas de código (LOC) y el volumen de Halstead sin contribuir a la carga de mantenimiento del código activo. Un programa con 600 líneas de código obsoleto y 200 líneas de código activo tiene un índice de mantenimiento (MI) que lo penaliza por el código obsoleto, aunque este sea irrelevante para el costo de cambio.

Métrica complementaria: Porcentaje de código muerto, que indica la proporción de sentencias PROCEDURE DIVISION inaccesibles desde cualquier ruta de ejecución de producción. Un alto porcentaje de código muerto indica que el volumen de líneas de código (LOC) y el volumen de Halstead calculados por MI están significativamente inflados.

Un conjunto completo de métricas COBOL

Ninguna métrica por sí sola refleja la mantenibilidad de COBOL. El siguiente conjunto de herramientas, utilizado en conjunto, proporciona una visión completa:

MétricoQué mideNota específica de COBOLUso primario
Índice de mantenibilidadFacilidad general de mantenimiento (compuesto)Aplicar a las declaraciones de la DIVISIÓN DE PROCEDIMIENTOS; verificar el manejo de COPIASPuntuación de calidad de referencia; clasificación de la cartera
Complejidad ciclomáticaNúmero de rutas de ejecución independientesIncluir EVALUAR CUÁNDO, REALIZAR HASTA, AL FINAL, EN CASO DE EXCEPCIÓNCambio de esfuerzo por programa; estimación del número de casos de prueba
Volumen de HalsteadCarga computacional (operadores + operandos)Cabe esperar valores superiores a los de programas de idiomas modernos equivalentes.Parte de MI; comparación entre programas dentro del portafolio de COBOL
COPIA Número de miembrosAcoplamiento de dependencias mediante definiciones compartidasLos programas con más de 15 miembros COPY requieren un análisis de impacto antes de cualquier cambio.Clasificación del riesgo de cambio
Fan-In (Llamado por)¿Cuántos programas llaman a este?Principal factor determinante del riesgo de cambio para los subprogramasSecuenciación de migración; cambio del umbral de autorización
Código muerto %Porcentaje de código de procedimiento inalcanzableInflar LOC/HV si no está excluido; excluir del alcance de la conversiónReducción del alcance para la modernización
Profundidad de dependencia de JCLProfundidad de la cadena de trabajo por lotes descendenteNo se puede calcular solo a partir del código fuente COBOL; requiere análisis JCL.Riesgo de cambio operativo; alcance de las pruebas
Profundidad de PERFORM anidadaNivel máximo de anidamiento de llamadas PERFORMEl anidamiento profundo indica una complejidad estructural que no se refleja en CC.Prioridad de refactorización

Calibración de umbrales para COBOL

Los umbrales MI estándar se derivan de bases de código de lenguajes modernos y no se aplican directamente a COBOL. La siguiente tabla compara los umbrales estándar con sus equivalentes adecuados para COBOL y explica la lógica del ajuste.

Rango de puntuaciónInterpretación estándarInterpretación de COBOLRazón fundamental
85-100Fácil mantenimientoAltamente mantenible (consistente)Los mejores programas COBOL obtienen una puntuación en este rango, con una estructura limpia y un tamaño adecuado.
65-84Mantenimiento moderadoModeradamente mantenible, revisar el acoplamiento COPY y el fan-inEl umbral estándar se mantiene, pero las métricas complementarias son más importantes aquí.
50-64Malo, se necesita refactorizaciónMarginal, evaluar en contextoMuchos programas COBOL bien estructurados obtienen una puntuación aquí simplemente por su verbosidad; utilice CC y fan-in para distinguir los problemas reales de los artefactos de sintaxis.
25-49Muy pobreDeficiente, probablemente con alta CC y/o LOC excesivoLos programas en este rango indican de manera fiable problemas estructurales, no solo verbosidad de COBOL.
0-24Refactorización crítica e importanteCrítico, máxima prioridad para remediación o retiroDe acuerdo con la interpretación estándar

Guía clave para la calibración: Ejecute MI en todo su portafolio de COBOL antes de establecer umbrales específicos para cada programa. Calcule la mediana y el rango intercuartil del portafolio. Establezca el umbral de "atención requerida" en el percentil 25 de su propio portafolio, es decir, en los programas del cuartil inferior de su base de código específica, no en los programas que obtienen una puntuación inferior a un umbral derivado de programas Java. Este enfoque se autocalibra y tiene en cuenta el efecto de verbosidad sistemática de COBOL.

Uso de la información de gestión para la toma de decisiones de modernización

Las puntuaciones de inteligencia de mercado (IM) adquieren mayor valor cuando sirven de base para decisiones operativas específicas. Estas son las principales aplicaciones.

Secuenciación de las oleadas de migración. Los programas con puntuaciones MI altas (bien mantenidos, de baja complejidad) son los mejores candidatos para las primeras oleadas de migración. Son más fáciles de validar, tienen menos probabilidades de contener casos límite no documentados y conllevan un menor riesgo de generar un comportamiento inesperado en el entorno migrado. Los programas con puntuaciones MI bajas deben migrarse en oleadas posteriores, una vez que el equipo haya adquirido experiencia y confianza, y tras una extracción exhaustiva de la lógica de negocio.

Priorización del mantenimiento. Los programas con un índice de mantenimiento inferior al percentil 25 que además presentan una alta dependencia entre programas (llamados por muchos otros) o una alta profundidad de dependencia en la lista de compatibilidad de archivos (JCL) representan la combinación de mayor riesgo: programas estructuralmente complejos de los que dependen muchos otros. Estos son los programas con mayor probabilidad de generar defectos relacionados con cambios y los más costosos de corregir cuando se producen. Deberían ser los primeros objetivos de un programa de reducción de la deuda técnica.

Decisiones de desarrollo interno vs. compra. Al evaluar si conviene mantener un programa COBOL a largo plazo o reemplazarlo por una alternativa SaaS o moderna, el índice MI y el historial de costos de cambio proporcionan la base cuantitativa para el cálculo de desarrollo interno vs. compra. Un programa con MI = 30, modificado quince veces en los últimos tres años, y cada modificación ha tomado mucho más tiempo del estimado, tiene un costo de mantenimiento documentado que se puede comparar con el costo de reemplazo.

Umbrales de autorización de cambios. Algunas organizaciones utilizan puntuaciones MI para determinar el nivel de autorización de cambios requerido. Los programas que se encuentran por debajo de un determinado umbral MI requieren una revisión más rigurosa, pruebas independientes y una aprobación adicional antes de su implementación en producción. Esto crea un proceso de control de cambios que prioriza la calidad sin necesidad de evaluar manualmente cada cambio.

Lo único que la inteligencia de mercado (IM) no puede hacer es predecir el impacto empresarial de un cambio. Un programa con IM = 85 que realiza cálculos de capital regulatorio requiere al menos la misma cantidad de pruebas y validación que un programa con IM = 40 que realiza una función de informes de bajo riesgo. La IM mide el esfuerzo del cambio, no sus consecuencias. Ambas dimensiones son necesarias para una evaluación de riesgos completa.

Cómo SMART TS XL Establece y realiza un seguimiento de las métricas de mantenibilidad de COBOL.

Calcular la información de gestión (MI) para un solo programa COBOL es sencillo. Calcularla con precisión para un conjunto de miles de programas, teniendo en cuenta la expansión de COPY, identificando el código muerto y complementando la MI con las métricas adicionales que le faltan, requiere un análisis automatizado a gran escala.

SMART TS XL, análisis de código estático Calcula simultáneamente el conjunto completo de métricas COBOL descrito en esta guía para todo el portafolio. MI se calcula utilizando recuentos de sentencias de PROCEDURE DIVISION en lugar de líneas fuente totales, con expansión COPY realizada antes del análisis para garantizar que las definiciones de datos compartidas se atribuyan correctamente. La complejidad ciclomática tiene en cuenta las cláusulas EVALUATE WHEN, las condiciones PERFORM UNTIL y las ramas del manejador de excepciones, no solo las sentencias IF. El volumen de Halstead se calcula a partir de verbos COBOL y operandos de datos en PROCEDURE DIVISION.

Crucialmente, SMART TS XL complementa MI con las métricas que le faltan a la fórmula. mapeo de dependencias de aplicaciones produce los valores de fan-in, recuentos de llamados por, para cada programa en la cartera, identificando programas de alto riesgo independientemente de su puntuación MI. Expansión JCL Esta capacidad proporciona la profundidad de dependencia JCL para cada programa, conectando el análisis MI a nivel de COBOL con el contexto de riesgo operacional que solo el análisis JCL puede revelar.

La identificación de código muerto mediante la función de análisis de impacto señala los párrafos y secciones sin rutas de ejecución entrantes, lo que permite excluir el código muerto del cálculo de MI y proporciona la métrica de porcentaje de código muerto que determina si la baja puntuación de MI de un programa refleja una complejidad genuina o un número de líneas de código inflado.

La función de búsqueda empresarial permite consultar el conjunto completo de datos de métricas: encuentre todos los programas con MI inferior a 40 y fan-in superior a 20, ordenados por profundidad de dependencia JCL, y los objetivos de remediación de mayor prioridad en el portafolio, en una sola consulta a través de millones de líneas de COBOL. Este inventario de métricas consultable es la base de las aplicaciones de priorización de mantenimiento, secuenciación de migración y autorización de cambios descritas anteriormente.

Finalmente, el índice de mejora (IM), que se monitoriza a lo largo del tiempo y se recalcula después de cada ciclo de cambio significativo, muestra si el programa está mejorando o deteriorándose. SMART TS XLEl análisis se realiza sobre el código fuente actual en lugar de sobre instantáneas almacenadas en caché, lo que garantiza que las métricas reflejen el estado real del código base en el momento de cada análisis, en lugar de una evaluación puntual que se va quedando obsoleta.

Métricas que se ajustan al lenguaje

El Índice de Mantenibilidad es una métrica válida y valiosa para los portafolios de COBOL, pero solo si se aplica comprendiendo cómo interactúan las características sintácticas de COBOL con sus componentes. Aplicar umbrales genéricos a los programas COBOL produce resultados engañosos. Complementar el MI con las métricas que omite (acoplamiento COPY, fan-in, profundidad de dependencia JCL, porcentaje de código muerto) ofrece una imagen que se corresponde con la experiencia real de los desarrolladores al trabajar en un portafolio de COBOL.

Las organizaciones que utilizan estas métricas de forma eficaz son aquellas que las consideran un punto de partida para un diálogo informado, no un veredicto definitivo sobre la calidad del programa. Una puntuación de MI es una señal. Vale la pena seguir esta señal, ya que apunta consistentemente hacia los programas cuyo cambio resulta costoso, cuya modificación conlleva riesgos y que merecen ser abordados antes de que comience la modernización. Lo que la MI no puede hacer es reemplazar el criterio de un desarrollador que lee el código, ni sustituir el análisis estructural que revela las dependencias y la lógica de negocio que ninguna métrica por sí sola puede capturar.