La primera vez que me engañes sera culpa tuya;la segunda vez sera mia.
Proverbio árabe

Archivos en la categoría Calidad

Calidad … superficial

Como me estoy retrasando con la continuación sobre mi productividad personal, quiero compartir con vosotros una reflexión sobre calidad. Hablemos de vender chapa y pintura.

Hubo un tiempo en que me encontré con una funcionalidad que llevaba años en producción sin ser modificada, que estaba cubierta con la implementación de 18 métodos test diferentes. A priori para una persona que llegase nueva al proyecto, podría ser una funcionalidad confiable, podría ser un código tranquilamente refactorizable ya que si el nuevo código supera los 18 test seguirá siendo confiable.

Cuando me puse a rascar…

Esta funcionalidad estaba implementada en un método de unas 60 líneas en una capa errónea (service, cuando se trataba de un proceso batch), en una clase con unas 4.200 líneas. Tras rascarla un poco la dejé en 3.200 líneas, y aún quedaban métodos duplicados, métodos que había que sacar a otras clases (como éste), y bloques de código que había que encapsular en nuevos métodos. Calculo que el tamaño adecuado serían unas 750 líneas. De las más de 14mil líneas de código de su clase de test, ni hablamos.

Lo bueno, si breve, dos veces bueno. Y si está en su sito, tres veces. Y si se entiende a la primera, cuatro veces. Y si hace lo que debe y no hace lo que no debe, 10 veces.

La implementación tenía un return dentro de un bucle anidado dentro de otro bucle, lo que provocaba un fallo ya que lo que realmente se quería era un break (salir del bucle anidado, no del método). Dentro del primer bucle había 5 estructuras if anidadas, luego venía el segundo bucle que contenía otro if que contenía el erróneo return. Por supuesto, 0 trazas para garantizar que un método con esta estructura sea entendible y certero.

Niños, ojo al utilizar sentencias de control del flujo del programa, cada método debe tener 0 breaks, 0 returns (si es un void) o 1 return.

Por si no fueran pocos los errores que ya introducía ese return, se comprobaba la integridad de los datos desde el punto de vista del negocio, pero no se hacía nada en caso de no superarse lo que ocurría en el 12% de los casos, por lo cual el 12% de los casos llevaba fallando desde el principio de los tiempos en esta funcionalidad, pero apostaría sobre seguro que ese mismo 12% de casos estaría fallando desde el principio de los tiempos en otras funcionalidades. Y después de comprobarlo, al menos encontré otras 2 funcionalidades en las que fallaban.

No te fíes aunque baje Dios y te diga que funciona, compruébalo tú mismo.

El proyecto cuenta con literalmente cientos de líneas de código y pruebas (aunque extrapolando este caso al proyecto, seguro que podríamos apañarnos con 20mil líneas de código), y los WAR generados con su “arquitectura” (indocumentada) pesan más de 80 megas (el proyecto más complejo tecnológicamente en el que he estado, struts, spring, hibernate, ibatis, jasperReports, 2 drivers de bbdd, servicios web, encajado en un Single Sign On, jquery y me dejo algo, pesaba 20 megas).

Los proyectos Java se deberían basar en dos conceptos : Modularidad y Reusabilidad.

Finalmente, el código fue proporcionado por un proveedor externo, y al comunicarle que me disponía a limpiar su código me respondió que si modificaba el código perdería la garantía. Tenían notificados errores sin resolver desde hace un año.

Las convenciones de código y las buenas prácticas, sirven para que tu garantía tenga valor.

Qué pensarías de este proveedor? Qué valor le daríais a su garantía? Vosotros confiaríais el arreglo de ese embolao al mismo que lo creó?

PD, esperas que nos saquen de la crisis los mismos que nos metieron? Qué haces para impedirlo?

Por qué la calidad no es negociable

Releyendo el libro de “Scrum y XP desde las trincheras“, cuyo original en inglés puedes obtener gratuitamente (o donando) aquí desde InfoQ, o la versión traducida al español desde proyectalis aquí, he llegado a un epígrafe titulado como esta entrada, “Por qué la calidad no es negociable“, que me ha provocado la necesidad de compartir este pilar básico de las negociaciones con clientes.

El autor, Henrik Kniberg, diferencia dentro de nuestros sistemas entre

  • la calidad externa, la que perciben los usuarios del sistema.
  • la calidad interna, la que tienen un profundo efecto en la mantenibilidad del sistema.

La calidad externa recomienda tratarla como parte del alcance del producto, posibilitando la entrega de una versión con una pobre UX por ejemplo, para posteriormente entregar una segunda versión mejorada.

La calidad interna recomienda que sea completamente innegociable (salvo necesidades mayúsculamente imperativas), ya que el ahorro actual de tiempo prácticamente nunca compensa el deterioro que sufre el sistema y el coste de su futura reparación.

Cuesta valorar lo que no ves. Los clientes piensan en el código como un escrito con faltas de ortografía, podía estar mejor pero ahora cumple su función (se entiende) y ya le quitarás las faltas cuando saques un rato: cuando venga los errores es cuando se preocuparán.

En esos casos imperativos Henrik propone que negociemos el alcance de la historia o iteración:

Cliente – Respeto vuestra estimación de 6 puntos de historia (PH), pero estoy seguro que podríamos usar algún apaño rápido para hacerlo en la mitad de tiempo.

Equipo de desarrollo – Bueno, ya que esta historia es especialmente importante para ti que la entreguemos pronto, ¿podemos reducir su alcance de forma que sea más fácil de implementar? ¿Podemos sacar alguna otra historia de la iteración?

Mi experiencia me permite completar este diálogo :

Cliente – Imposible, los tiempos nos los marca el mercado y necesitamos todas las funcionalidades acordadas.

Equipo de desarrollo – Entonces podemos implementar ahora un atajo estimado en 3 PHs pero comprometerá la integridad de los datos en producción y degradará la calidad del sistema. Debemos añadir a la pila del producto otra tarea muy urgente para completar esta historia aceptablemente y arreglar los errores que generará, estimada en 7 PHs.

Cliente – Pero la siguiente iteración también es muy urgente e importante!

Equipo de desarrollo – Si retrasamos más esta nueva historia, será también más costosa ya que construiremos sobre unos cimientos deficientes e introducirá más errores en la base de datos de producción. Estimamos que cada mes de retraso supondrá un coste creciente de al menos 3 PHs.

Cliente – …

Equipo de desarrollo – La decisión es tuya. ¿Qué haremos?

Es muy importante no limitarse a dar visibilidad sino aseguranos de que el cliente entienda que el arreglo costará más con el tiempo y que los errores futuros a corregir están fuera de garantía, porque sino se aferrarán siempre a tu primera cifra.

Debemos informar hoy del coste futuro de la brecha de calidad para que nuestro cliente puede tomar una decisión informada. Si cree que no es tan urgente mantendremos la calidad interna de nuestro sistema intacta; si cree que es mucho más urgente ya sabe el coste que tendrá.

Ante un cliente que no quiere reconocer nunca ese coste futuro, es mejor asumir un retraso temprano dejando fuera algo y la consiguiente bronca que arrastrar ciertos errores. Tus habilidades de comunicación y negociación habrán fracasado, el que haya gente que no quiere escuchar no es una excusa, pero salvarás tu proyecto: si todo es urgente es que realmente nada es tan urgente.

Todo esto es aplicable a cualquier metodología que se siga, no sólo es válido en Scrum!!!

PostData

Hay libros que hay que releer periódicamente, no sólo libros técnicos. “Scrum y XP desde las trincheras” es uno de estos clásicos por su brevedad, simplicidad e importancia del mensaje que trasmite.

¿Qué otros libros recomendarías leer y releer?

Mike Rozlog: Charla sobre auditar tu código

Las herramientas para auditar tu código son una buena guía para que los desarrolladores aprendamos de las mejores prácticas, permitiendo mejorar no sólo el código de nuestro proyecto actual sino también aprender de los errores de los demás y modificar nuestra forma de trabajar para evitar estos problemas en el futuro.

Aquí podéis ver una charla en inglés vista en InfoQ sobre los 5 típicos errores que todos deberíamos evitar al desarrollar, a cargo de Mike Rozlog: Five Static Code Audits Every Developer Should Know and Use.

Comenta