¿Cómo podemos discernir que una aplicación es de mayor calidad que otra?
Todos defendemos nuestro trabajo, sin ninguna duda, aunque hay elementos subjetivos para ello y también otros muy objetivos e incontestables.
Lejos de plantear una definición demasiado académica y siendo pragmáticos, podemos decir que un software es de calidad no solo cuando cumple correctamente la funcionalidad requerida y aporta valor al cliente que la usa (y que paga por ella). También lo consideramos de mejor calidad cuando el coste de su mantenimiento es bajo y la dificultad para introducir nuevos cambios (nuevos requisitos) es baja o trivial. Esto último es, en realidad, el mantra de todo este libro, de modo que lo vas a leer a menudo hasta que se grabe en tu ADN de desarrollador.
Fácil de decir, pero, en cierta medida, difícil de conseguir. Como muchos otros temas, lo simple no siempre es fácil. En mi opinión, esta es la definición de calidad de software más interesante para tener en cuenta en el día a día como programador en cualquier compañía, porque lo que persigue cualquier empresa es rentabilizar al máximo cada esfuerzo que se realiza para crear un nuevo producto.
Muchos desarrolladores, por falta de experiencia, por presiones de tiempo o por ausencia de disciplina metodológica, nos quedamos atascados en ese primer aspecto de la calidad que comentamos en el párrafo anterior: cumplir la funcionalidad y punto. Dejamos la implementación de la funcionalidad X tal como la escribimos y resolvimos por primera vez, y así se queda hasta el final de los tiempos, suponiendo en ocasiones un auténtico lastre y acumulando una deuda técnica que algún día nos pasará factura, a nosotros o a los compañeros que tengan que retomar el proyecto.
Sin embargo, ya sabemos que en cualquier negocio o proyecto, salvo excepciones muy contadas, a nuestro código se le va a exigir cambiar, sí o sí. Precisamente de esa realidad («todo software va a sufrir cambios») nació, en esencia, el movimiento de software ágil como forma de abordar mejor el código que escribimos, dando lugar a técnicas específicas, metodologías, técnicas de pruebas y al concepto de diseño ágil, entre otras cosas.
Métete esto bien en la cabeza: debemos escribir código pensando en que necesariamente sufrirá cambios. La capacidad de aceptarlos determinará el coste de mantenerlo e incluso el éxito o el fracaso del proyecto. Y ya sabes: si tu trabajo fracasa, te obligarán a buscarte otro.
Recapitulemos: no programamos únicamente para cumplir con cierta funcionalidad que se exige en la aplicación «hoy»; también para hacer funcionar un negocio (que es el que paga en última instancia). Pocos negocios son estáticos y no necesitan cambiar, optimizarse o mejorar continuamente. En ello está, además, la esencia de la nueva economía de este siglo, en la que aparecen productos de un día para otro al mismo ritmo que otros evolucionan o desaparecen.
Es cierto que no existe una bola de cristal que nos anticipe qué cambios concretos tendremos que introducir, pero veremos que, sin suponer más esfuerzo, podemos programar de un modo que facilite la inclusión de nueva funcionalidad en el futuro. Si, por poner un ejemplo, de verdad crees que crear pruebas te «retrasa» o piensas que programar siguiendo principios de diseño es un rollo (porque aún no comprendes bien su razón de ser y entiendo que muchos de ellos son sutiles), entonces trabajas bajo una dinámica de pan para hoy y hambre para mañana y todavía no sabes que esas prácticas, en realidad, mejoran tu productividad y la calidad de tu trabajo.
En este sentido, es fácil determinar si una aplicación es de calidad o no: tan solo tenemos que mirar los siguientes aspectos:
- El código es simple (fácil de entender). La habilidad de un buen programador reside, básicamente, en encontrar soluciones sencillas a problemas que no lo son tanto y en desmenuzar un problema grande, abstrayéndolo en muchos otros más pequeños y manejables.
- También es legible (fácil de leer y de seguir). El código debe ser fácil de leer por cualquier miembro del equipo y debe poder ser asumido con facilidad por cualquier nuevo miembro que se incorpore. Me atrevo a decir que no hacen falta gurús para hacer las cosas bien.
- Existen pruebas con cobertura suficiente. Un porcentaje alto del código de la aplicación está cubierto por pruebas, y estas son de distinto tipo, como veremos en el capítulo dedicado al testing. Es un tema extraordinariamente amplio, de modo que un tester competente tiene habilidades técnicas diferentes a las de un desarrollador. Con los pies en la tierra y siendo prácticos, nuestro proyecto debe contar, al menos, con una buena batería de pruebas unitarias y de integración.
- El diseño y el código son homogéneos y coherentes. No programamos del primer modo que se nos ocurre para solucionar algo; eso puede valer como primera aproximación, pero debemos mantener el diseño seguido en toda la solución y alinearlo con el resto del código de la aplicación en estilo, uso de librerías externas, normas consensuadas para hacer las cosas, etc. Nada peor que identificar una parte específica de un proyecto y reconocer en ella la mano concreta de un compañero.
- El desarrollador dedica la mayor parte de su tiempo a añadir nueva funcionalidad, no a corregir errores. Si pasamos mucho tiempo detectando o corrigiendo errores, ya sabemos que la aplicación se aleja de la definición de calidad que hemos dado más arriba y, por tanto, queda mucho trabajo para mejorarla.
- A producción solo llegan defectos pequeños, si es que existen, pero nunca errores críticos. Producción es el entorno final en el que se ejecuta la aplicación para dar servicio al cliente. Ya hemos dicho al comienzo que el coste de probar exhaustivamente un software de cierto tamaño es extraordinariamente alto. No es profesional liberar una versión del proyecto que presente en explotación errores graves que impidan el buen funcionamiento de la actividad a la que da soporte. Siguiendo el símil de los arquitectos… ¿os imagináis un edificio que al día siguiente de su inauguración comienza a mostrar grietas?
- Las métricas más básicas dan buenos valores. Existen muchas métricas para evaluar diferentes aspectos del código, pero algunas son fáciles de obtener y nos pueden ayudar a detectar ciertos problemas: el número de líneas por método, la complejidad ciclomática, la detección de código que nunca se ejecuta, etc.
En los siguientes capítulos hablaremos de todos estos aspectos y los describiremos a nivel técnico con mayor detalle.
Nota: Este es el capítulo completo titulado «Qué es la calidad del software», incluido en El Libro Práctico del Programador Ágil.