domingo, enero 27, 2013

La importancia del software mantenible


Una aplicación puede ser bonita, usable, rápida, eficiente,... todas ellas características relativas al estado o comportamiento actuales. Pero se nos olvida que el software tiene una fuerte componente de evolución en el tiempo y ahí es donde entra la mantenibilidad.
Esta característica, que afecta enormemente al futuro de una aplicación, es obviada a menudo, a pesar de ser una de las que más diferencia el producto creado por un desarrollador aficionado del creado por uno profesional.


Los componentes del software pueden ser peor que una maraña

Mantenible

Si quisiéramos el mejor coche del mundo y no tuviéramos límites económicos, juntaríamos a varios científicos, que nos construirían lo mejor de lo mejor: mucha potencia, bajo consumo, cómodo, fácil de aparcar, maletero muy aprovechable,... ¡lo mejor de lo mejor! Pero, puede ser que, cuando pinchemos una rueda, haya que llevarlo al taller por las herramientas tan complejas para quitar y poner la rueda; puede que no hubiera ninguna baca compatible; puede que la revisión periódica costara como medio coche por lo dificil de desarmar, mirar y ajustar,...
Con el software es, incluso peor. Si queremos adaptar la aplicación a una evolución del sistema operativo, a una nueva resolución de pantalla, añadir, cambiar o corregir una funcionalidad,... estamos poniendo a prueba la mantenibilidad del software.
La IEEE define mantenibilidad como “ La facilidad con que un sistema software o componente puede ser modificado para corregir faltas, mejorar rendimiento u otros atributos, o adaptar a un entorno cambiante“ (traducción libre) pero que se puede resumir como “facil de entender y cambiar”.

Conceptos que pueden ayudarnos a gestionar la mantenibilidad

  • KISS (Keep it simple, studid). Hacer las cosas sencillas, claras, que se puedan entender facilmente. Hay que evitar las ideas maravillosas que, aunque sean “mejores”, luego sean muy difíciles de retormar, incluso, por su autor original.
  • No lo vas a necesitar VS. Por si acaso. Durante el desarrollo, muchas veces vamos por delante de futuros requerimientos y, en previsión de algo muy complejo tu, que eres muy listo y experto, tardas el doble en tener lo que había pedido ya el usuario, por dejarlo super-extensible y super-preparado para el futuro. Pero eso no suele ser rentable e, incluso, si me apuras, puesto que puedes haberte esforzado en la dirección equivocada. Podemos recordar el mantra de “Es infinita la capacidad que tiene el usuario de sorprender al desarrollador con sus peticiones”
  • No repetir. En innumerables ocasiones, ante problemas similares, copiamos un trozo de solución empleado en un lugar, y luego pegamos en otro, igual o casi igual. Para evitar esto hay múltiples técnicas como la modularidad, herencia, bibliotecas, paquetes, componentes,...
  • Si funciona no lo toques. Dado que los errores pueden aparecer en cualquier punto, hay que evitar incluir nuevos puntos de riesgo, por lo que no vamos a tocar nada salvo que sea necesario.

Metodologías de desarrollo

Lo primero de todo. Aunque muchas veces se pone como ejemplo para saber si algo es mantenible el código realizado, TODO ESTE ARTÍCULO va dirigido a todas las fases o etapas de creación de software, especialmente análisis, diseño, construcción y mantenimiento.
Un análisis sencillo, que refleje ideas concretas, claras y sencillas, dará lugar a un diseño, también sencillo y limpio, que hará que la codificación sea más sencilla, con menos dependencias y alardes innecesarios, para dar lugar a un mantenimiento más directo y con menos efectos secundarios. Si durante dicho mantenimiento (normalmente la etapa más larga de un software), conseguimos mantenernos en el camino de la mantenibilidad, nuestra vida y la del software serán más sencillos.
Si bien no siempre se menciona expresamente, todas las metodologías de desarrollo incluyen entre sus objetivos que el producto final sea mantenible.
Desde las primeras metodologías, se han tenido en cuenta el acoplamiento y la modularidad de los proyectos, siendo deseable un bajo acoplamiento y una alta modularidad.
Las metodologías orientadas a objetos buscan clases coherentes, con bajo acoplamiento, acercando el código a los datos y estado relevantes para su comportamiento.
La metodología ágil “Extreme Programing” incluye, entre sus 12 prácticas, la de “Programación en parejas”. Si ambos desarrolladores se sientan juntos a desarrollar, y ambos entienden el resultado, si lo ha pensado uno y explicado al otro, si ambos lo han repasado,... será más mantenible el resultado final.

Medible

Una de las lecciones básicas en la gestión de proyectos es que “lo que no es medible no se puede controlar”, y con la mantenibilidad ocurre lo mismo.
Multitud de herramientas se han creado para darnos algunas métricas automáticas. Como tales, no se deben tomar al pie de la letra, ya nos dan una pista, pero luego hay que estudiar los casos particulares y las posibles excepciones admitibles.
En algunos entornos, a la hora de subir al repositorio el código, antes se le pasan unos chequeos y si se activan ciertas alarmas (se superan ciertos umbrales para ciertas métricas) salta alarma y no se permite la subida del código.

Profundidad de herencia

Indica el número de definiciones de clase que hay entre esta y la raíz de toda la jerarquía. Por ejemplo, en muchos lenguajes / arquitecturas todo deriva de Object. En ese caso, sería cuantas clases hay entre la actual y Object ( a base de extend, inherits,...). Cuando más profunda es la jerarquía, más dificil será entender donde se definien y se vuelven a definir determinados métodos y atributos. 
Caso de Profundidad de herencia habitual
 

Complejidad ciclomática

Mide la complejidad estructural del sistema. Se calcula calculando el número de rutas de acceso del código diferentes del flujo del programa. Un programa que tenga un flujo de control complejo requerirá más pruebas para lograr una buena cobertura de código (pruebas de caja blanca) y será más dificil de mantener.

Acoplamiento de clases

Para cada clase, calcular cuantos parámetros necesita, con cuantas clases colabora directamente para lograr completar su comportamiento, y en general cuantos elementos necesita y conforman su infraestructura para funcionar correctamente.
Acoplamiento de clases

Líneas de código

Número de líneas de código efectivo. Para ellas no cuentan las de los comentarios, ni las en blanco, ni las que no tienen significado para el código compilado. Se pueden calcular como total del proyecto, total por fichero, total por método,... Un recuento muy alto podría indicar que un método o clase intenta abarcar demasiado trabajo y podría ser adecuado dividirlo. También podría indicar la dificultad de mantener dicho elemento.


Por lo tanto, podemos concluir que, la mantenibilidad debe ser uno más de los objetivos que nos planteemos para el proyecto, y todo lo que sea fomentarlo, nos hará la vida más fácil en el futuro. Apoyándonos en herramientas o en nuestra experiencia, realiar esfuerzos dirigidos a su gestión y consecución serán siempre pasos adelante en nuestro proyecto.

1 comentario:

Jesus Castro dijo...

La mantenibilidad es importante, pero se vuelve un infierno y una tortura en los equipos de trabajo. Es la fuente N° 1 de peleas y discusiones en el desarrollo de software. Este tema conlleva peligrosamente al individuo al sindrome del perfeccionismo, a sabienda que ningun codigo sera perfecto, por mas que se apliquen tecnicas para mejorarlo. Sin embargo, hay muchos desarrolladores y gente de alto mando que no entienden esto. El ejemplo de Google lo dice todo: a pesar de la excelente calidad de su talento humano, sus productos siempre lo consideran en estado beta. El tema de la mantenibilidad hay que saberlo manejar.