Aplicación Legacy – Refactoring con el plugin SQALE (II)

LegacyTechDebtRefactoring3Como le hemos visto en el post anterior, no he personalizado el Quality Profile de SonarQube ni el modelo SQALE, para nuestra aplicación Legacy,  según nuestro contexto y  la orientación que queremos para la evaluación du su deuda técnica.

De hecho, hemos utilizado los resultados ‘out of the box’ para ilustrar un posible enfoque en la valoración del coste de refactorización, y presentar al equipo del proyecto y a los managers algunas ideas y áreas de mejora.

En otras palabras, nos interesa más el proceso que los resultados, por lo menos en el contexto de estos artículos.

Veamos ahora unas propuestas de plan de acción.

Corregir los defectos más críticos

La primera cosa que puedo hacer con el widget que me he configurado (ver Figura 1 – Los datos SQALE de la deuda técnica) es que nos cuesta:

  • 59.6 días para remediar las ‘Issues’ de tipo ‘Critical’ y más allá, es decir ‘Critical’ y ‘Blocker’.
  • 1 115.6 días para las ‘Issues’ ‘Major’, ‘Critical’ y ‘Blocker’.

Tengo la misma información en el siguiente widget:

Figura 1 – SQALE Remediation Cost por criticidad

Legacy Technical Debt Criticity

El área azul oscuro en cada una de las barras horizontales en este gráfico corresponde a la barra anterior, para calcular un coste por cada criticidad y el coste total, como se muestra en las dos columnas de la derecha.

Habíamos visto que no teníamos defectos de tipo ‘Blocker’ pero sí 753 de tipo ‘Critical’, la mayoría de ellos concentrados en dos reglas.

Figura 2 – Violaciónes a reglas ‘Critical’

C_World_Crticals

La siguiente figura lista los archivos que contienen estos defectos y los costes de remediación:

Figura 3 – SQALE Remediation Cost – Critical y Blockers

Legacy Technical Debt Files Critical Issues

Puedo abrir cada archivo en SonarQube, y elegir ver solo ciertas ‘Issues’. La siguiente figura muestra el programa ‘fltexp.c’ y unos defectos ‘Critical’.

LegacyTechfltexpCritical

Para cada uno de los 16 defectos de tipo crítico en este programa, puedo ver:

  • La línea de código.
  • El coste de remediación de este defecto, tal como está configurado en el plugin SQALE: 1 hora en el primer caso (MISRA C++ 6-6-1) y 15 minutos en el segundo (MISRA C++ 5-14-1).

Basandonos en estos números, podemos proponer una primera acción de refactorización de los componentes con defectos críticos para un total de aproximadamente 60 días, o 12 días para un equipo de 5 personas.

En realidad, voy a trabajar con el equipo de proyecto para estimar los defectos que ellos ven o no críticos (o ‘Blocker’), el tiempo que consideran necesario para resolver cada uno, y así establecer un Quality Profile (conjunto de reglas SonarQube) personalizado.

Restablecer el SQALE Rating al nivel A

Con el widget que me he configurado (ver Figura 1 – Los datos de la deuda técnica SQALE), también puedo ver que nos cuesta 291.9 días para llevar el SQALE Rating desde B, el nivel actual hacia una clasificación de nivel A. El SQALE Rating mide la carga de la deuda en la aplicación, de la siguiente manera en nuestro caso:

  • B: entre 10% y 20%.
  • A: menos o igual a 10%.

Con 18.5 días de trabajo al mes, estos 291.9 días representan 15.8 meses en total, o 3 meses y 3 días por desarrollador para un equipo de 5 personas. Si añado una carga de gestión de proyectos de 20%, que es la cifra por defecto para toda planificación, pasamos a 3 meses y 15 días por desarrollador.

Hemos visto que la realización de las pruebas de caracterización necesitan unos tres meses, con un poco de margen para la gestión de proyecto, lo que es aceptable en un contexto de transferencia de conocimientos. Si añadimos otros 3 meses y algunos días, nuestro proyecto de refactorización pasa a seis o siete meses, que creo aceptable para fiabilizar nuestra aplicación con pruebas unitarias y llevarla a un nivel muy decente de deuda técnica.

En realidad, es muy difícil para los directivos de justificar a los usuarios paralizar el desarrollo – especialmente toda corrección – durante ese período. No sé nada del backlog en términos de ‘Change Requests’ de los usuarios, así como las cargas promedio de corrección por mes que debemos tomar en cuenta en la planificación de la refactorización: así que voy a satisfecerme de sólo estos 292 días y voy a tratar optimizarlos con el fin de construir un plan de mejoras, admisible o al menos posible para los directivos.

La pirámide SQALE nos ayudará a elegir entre las diferentes categorías de violaciónes de ‘best practices’.

Figura 4 – SQALE Tecnical Debt Pyramid

Legacy Technical Debt SQALE Pyramid

Cada factor de nivel superior tiene una serie de ‘características’ que recogerán cada una sus propias métricas. La siguiente figura muestra la pantalla de configuración SQALE en SonarQube, que se utiliza para establecer el coste de remediación para cada violación a una ‘best practice’ de programación dentro de cada categoría, en el siguiente ejemplo, las ‘Characteristics’ de ‘Testability’.

Figura 5 – Configuración de reglas en el modelo SQALE

Legacy Technical Debt SQALE Quality Profile Configuration

No tengo reglas para la ‘Reusability’ en este perfil para los lenguajes C/C++, lo que explica la deuda técnica a 0 en este factor (ver la Figura 4 anterior).

La ‘Portability’ ve una única regla infringida, con una deuda técnica de 3.5 días, pero es importante solamente en el caso de volver a escribir la aplicación en C++. Entonces esto debe tenerse en cuenta como parte de una reingeniería, pero no una refactorización.

Figura 6 – Regla de ‘Portability’

Legacy Technical Debt SQALE Characteristic Portability

Es lo mismo para las reglas relativas a la ‘Testability’ (ver la figura 5 anterior como ‘Avoid too complex file’, ‘Avoid too complex function’, el número de parámetros de una función o el uso de ‘Goto’ y ‘Continue’: refactorizar este tipo de defecto requiere un rediseño de la aplicación, por lo que una vez más, se debe considerar en una reingeniería. Porque si necesitamos pensar de nuevo el diseño y la arquitectura de la aplicación con el fin de distribuir mejor la complejidad, entonces podemos tomar la oportunidad de volver a escribirla en un lenguaje orientado a objetos como C++, y beneficiarse de la herencia, la encapsulación y el polimorfismo.

Lo mismo para la ‘Changeability’. La siguiente figura muestra el SQALE Sunburst con:

  • En el nivel 1, los diferentes factores de Maintainability, Testability, Reliability, etc.
  • En el Nivel 2, las ‘características’ dentro de estos factores, como Undestandibility et Readibility pour la Maintainability.
  • En el Nivel 3, las reglas dentro de cada característica.

Figura 7 – Reglas de ‘Changeability’ en el SQALE Sunburst

Legacy Technical Debt SQALE Sunburst Changeability

Podemos ver en esta figura que los 13.7 días de deuda técnica para la ‘Changeability’ cubre una sola regla de ‘if’ anidado. Lo más tenemos ‘if’ dentro de ‘if’, lo más difícil es entender el código, y más alto el riesgo de introducir un error en relación con un cambio en el código.

Una regla de este tipo podría encontrarse también en la ‘característica’ de ‘Understandibility’. De hecho, muchas de las reglas de ‘Maintainability’ suelen ser candidatas para el grupo ‘Changeability’. Razón por la cual se recomienda de nuevo personalizar el modelo SQALE de acuerdo con su propio caso de uso, y no usarlo ‘out of the box’ como lo he hecho para este artículo.

En cualquier caso, estos defectos de ‘if’ anidados están bien dentro del objetivo de una refactorización, y podemos incluir estos 13.7 días en nuestro plan de acción.
En la figura siguiente, inserté (copiando y pegando) diferentes medidas:

  • La ‘Maintainability’ : 738 días refactorización en total, que se dividen en …
  • 505.6 días para la ‘Understandibility’ y 232.3 días para la ‘Readability’.

Figura 8 – SQALE Sunburst para la Maintainability

Legacy Technical Debt SQALE Sunburst Maintainability

Podemos observar que los costes de remediáción más altos se encuentran en reglas que no son necesariamente críticas. Que Microsoft no utilizó hace 20 años las convenciones de nomenclatura habitual hoy en día para las macros, no es ni sorprendente ni realmente muy importante, y la resolución de estos defectos a un coste de 128.1 días de refactorización no representa verdaderamente una ganancia lo suficiente importante como para considerar dicha acción.

Es lo mismo para el uso de ‘braces’ con ‘if..else’ que enumera una gran cantidad de ‘if’ en una única línea, de manera muy legible y muy comprensible sin necesidad de llaves en el principio y el final de esta instrucción. Poco beneficio pero un coste muy alto.

No, hay mejor que los defectos de ‘Maintainability’ para optimizar los 291 días necesarios para llevar la deuda técnica al nivel A. Podemos ver en la pirámide SQALE (Figura 4) que los defectos de ‘Reliability’ requieren 291.8 días de refactorización, lo que conviene a la perfección con nuestra cantidad de días disponibles (más o menos 3 meses para nuestro equipo de 5 personas).

Además, son defectos que afectan a la fiabilidad y la robustez de la aplicación, y por lo tanto presentan un riesgo para el cliente o el usuario final, cuando los defectos en la mantenibilidad sin duda pesan sobre los costes de mantenimiento, pero nunca causarán errores y bugs. Obviamente, esto depende de nuevo de la orientación que deseamos para el modelo SQALE, personalizando hacia la satisfacción del usuario o bien a favor de la preservación del presupuesto.

Primero veo que los 59.6 días que se necesitan para arreglar violaciónes de tipo ‘Critical’ (ver Figura 2 anterior) se refieren a las reglas dentro de la ‘Reliability’. La siguiente tabla muestra las diferentes normas y los costes de remediación.

Tabla 1 – Los costes de remediación de defectos en Reliability

Legacy Technical Debt Reliability Cost

Todas estas reglas mejoran la robustez de la aplicación y reducen el riesgo de error. Si añado los 13.7 días de ‘Changeability’ para eliminar los ‘if’ anidados, pasamos a 305.5 días, o 16.5 meses o 3 meses y 6 días por desarrollador (sin incluir los costes de gestión del proyecto).

Dicho esto, el peso de gestión del proyecto no debe ser enorme, ya que el plan de acción, desde un punto de vista operativo, está en el plugin SQALE. Hemos visto (Figura 2 del post anterior) que tenemos la distribución de programas en la escala del Rating SQALE. En la siguiente figura, puedo ver la lista de los archivos con la calificación más baja.

Figura 9 – SQALE Rating de los ficherosLegacy Technical Debt Rate Files

Cabe señalar que son archivos .h, de hecho con la nota muy baja debido al gran número de violaciónes a la regla ‘Macro names should comply with a naming convention’. De ahí la importancia de nuevo de personalizar el perfil de calidad y el modelo SQALE.

Gestión de la deuda técnica sobre la marcha

Corregir los defectos más críticos nos cuesta 59.5 días, cerca de 12 días para un equipo de 5 desarrolladores.

Reducir la deuda técnica de nuestra aplicación hacia un Rating SQALE de nivel A requiere aproximadamente 300 días, un poco más de tres meses para nuestro equipo, que los directivos o los stakeholders podrían considerar un esfuerzo demasiado alto.

Una solución intermedia sería una gestión de la deuda técnica sobre la marcha, es decir, en paralelo a las acciones de mantenimiento de la aplicación. Cada vez que un desarrollador tendrá que hacer un cambio o una corrección en un programa, también utilizará el plugin SQALE para verificar:

  • Si la deuda técnica aumenta. Este es el principal uso del plugin SQALE para un desarrollador, como ya comentamos en el post anterior: evitar la inflación de la deuda técnica y encontrarnos en unos años con una aplicación imposible de mantener.
  • Si es posible reducirla con los cambios que se deben alcanzar, centrándose en las reglas que hemos definido como críticas en el plugin SQALE.
  • Si no se ha incrementado la deuda técnica después de la aplicación de esos cambios.

No hay necesidad de pedir al desarrollador de cumplir con más de 10 buenas prácticas: más allá de eso, se vuelve demasiado complicado de recordar todo. También depende de la experiencia de los desarrolladores y su nivel de conocimiento, si no de madurez en las mejores prácticas. Pero incluso los desarrolladores más experimentados cometen errores porque no se puede evitar toda falta de atención y todo defecto. De ahí la importancia de un seguimiento regular de la deuda técnica.

Obviamente, la elección entre estas diferentes propuestas de planes de acción dependerá, no sólo del esfuerzo, sino también de los beneficios. ¿Podemos proponer una hipótesis para el retorno de inversión (ROI)?

Como este post ya es muy largo, voy a terminar este tema de refactorización con SQALE con una síntesis de nuestras propuestas y un intento de calcular el ROI. En el próximo post.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *