Dev from trenches

Un regard sur la qualité

Falta poco para terminar el desarrollo de la nueva versión del producto y estás con los últimos desarrollos. Vas un poco retrasado con respecto a la última previsión y de repente el equipo de Operaciones reporta un bug crítico. El cliente está nervioso porque se resuelva por la pérdida de servicio que está ocasionando. Tienes que parar para resolver este bug. Te lleva tres horas analizar su causa. Y otras cuatro resolverlo. Y otras tres más probarlo. Has perdido dos días y ahora te desviarás aún más del plan trazado.

Una situación típica si trabajas en el desarrollo de un producto. Sin embargo, lo que importa es la frecuencia con la que ocurre. Si ocurre con mucha frecuencia entonces las consecuencias son nefastas. El equipo estará sometido a un estrés continuo por el cambio de contexto y de ritmo. No es lo mismo resolver un bug bajo la presión de un SLA que desarrollar una nueva feature. El equipo no está motivado porque tiene la sensación de que su día a día consiste en nada más que resolver bugs deprisa y corriendo. No puede seguir el plan establecido. Cada día es una aventura y los días se hacen muy largos. Las previsiones de entrega que acuerdas con el cliente se incumplen constantemente. El sobre coste por la resolución de bugs se incrementa continuamente. Hay un riesgo en que el desarrollo de las nuevas features sea de mala calidad por intentar recuperar el tiempo perdido y entonces la historia se repita indefinidamente.

Siguen apareciendo bugs y más bugs. El equipo nuevamente tiene que parar el desarrollo de la versión actual para corregirlos. Las expectativas del cliente sobre el producto no se están cumpliendo. Al mismo tiempo, la expansión del producto es imparable debido a un cambio en el modelo de negocio del cliente. Ahora más que nunca se necesita un producto de calidad y cuya evolución se haga rápidamente para adaptarse a los nuevos requisitos del negocio. Esta situación de presión inevitablemente desemboca en un Big-Bang. Y de repente, !boom!, todo estalla y algo nuevo renace.

De repente, en momentos aislados de lucidez recuerdas las buenas prácticas de ingeniería de software que velan por una buena calidad del código. Comienzas a apreciar y valorar esta calidad simplemente por pura necesidad. La calidad de tu producto debe mejorar.

Apreciación de la calidad

Todo ha explotado por los aires. La relación con el cliente ha ido a peor y la posición del producto cae en picado. Necesitas parar durante un tiempo y analizar la situación.

El cliente requiere un producto con calidad. Interfaces de usuario bien diseñados y usables que aseguren una buena experiencia de usuario, un producto que ofrezca un buen servicio a los usuarios, que no haya bugs críticos, que el tiempo de resolución de los bugs sea bajo, que la evolución del producto sea rápida y no muy costosa.

La empresa necesita obtener un beneficio económico en la fabricación del producto, un coste de mantenimiento bajo, una evolución efectiva en coste y una calidad en el producto que le asegure continuidad en el negocio.

El problema es que no sabemos cómo fabricar un producto para que cumpla todos estos requisitos.

Lo primero que tienes que asumir es que probablemente aunque llames "producto" a lo que estás fabricando, no tenga la calidad suficiente como para llamarlo "producto".

La mejora de calidad de un producto ya fabricado tiene su coste. Probablemente un coste bastante más elevado que si lo construyeramos con calidad desde cero. Deberemos estar dispuestos a asumir este coste y decidir si seguimos con el proceso de mejora o no. Habrá que analizar qué volumen de negocio mueve el producto y qué perspectiva futura de negocio hay. Nos satisfará que el producto vaya mejorando su calidad y con ello el volumen de bugs baje considerablemente y el cliente vaya ganando confianza en el producto. Esto abrirá nuevas oportunidades de negocio. Sin embargo, nos cuesta aceptar este proceso de mejora y asumir su sobrecoste.

Equipo

Un producto de buena calidad sólo puede fabricarse por un equipo con buenas capacidades. Si tu producto es de baja calidad es posible que el equipo no sea capaz de hacerlo mejor. Es posible que el equipo sí que tenga potencial pero que haya una inercia de trabajo que no lo posibilite. Puede ser que el ritmo de trabajo marcado con plazos de entrega muy cortos imposibilite lograr esta calidad. Si estamos en esta última situación y se está dando mayor prioridad a los plazos de entrega que a la calidad, estamos hipotecando nuestro futuro.

Se necesita emplear tiempo y esfuerzo para formar un equipo con calidad. Y más allá, una cultura de equipo que aprecie y cuide la calidad. Cuando esto se consiga entonces se podrán fabricar productos de buena calidad. Sin embargo, se construye una cultura de calidad haciendo, experimentando, comparando y no solamente definiendo procesos desde la teoría. La mejora de calidad de nuestro producto conformará esta cultura de calidad.

Posiblemente se necesite incorporar al equipo a alguien externo que lidere la mejora de la calidad. La estrategia la definirá con el resto del equipo por ser éstos quienes mejor conozcan el producto, pero será esta nueva persona el motor del cambio. El equipo original tendrá que evolucionar y adaptarse a los nuevos procesos y formas de trabajo.

La causa raíz de producir software de mala calidad es que no se ven las consecuencias que provocan las malas prácticas en el desarrollo de software con respecto al servicio que ofrece el producto. No es que haya una única mala práctica que ocasione un producto de baja calidad, sino que hay un cúmulo de malas prácticas, cuyas consecuencias se van acumulando y ocasionan un producto pésimo. Cada línea de código cuenta y tiene su pequeña consecuencia que se irá acumulando con las demás. Y si tienes un producto con 500.000 líneas de código, pues calcula...

Hay que conseguir que el equipo asigne el valor apropiado a cada línea de código del producto. El modo más efectivo a corto plazo es hacerles ver que los bugs reportados son consecuencia de la mala calidad. Encuentro interesante la aproximación de Matt Mullenweg por la que cada persona del equipo esté al menos una semana al año en el equipo de Operaciones dando el soporte al usuario para que vea el servicio que ofrece el producto.

Otro modo es que vean que cuando se introduce una feature nueva hay que modificar partes del producto que conceptualmente no están relacionadas con esta feature. El equipo verá que ha modificado - indirectamente - varias veces la misma parte del producto y estarán hartos por no dar con una implementación definitiva. Otro modo es que vean como las estimaciones que dan para modificar código ya existente no se cumplen por la mala calidad del código. En el largo plazo lo mejor es hacer una comparativa de los bugs que se producían con versiones anteriores y los bugs que ahora se producen con versiones de mayor calidad. Y como su día a día ha mejorado.

Una vez que el equipo ya es consciente de la importancia de la calidad, puede ser que no sepa cómo mejorarla. Tendrás que mostrarles las buenas prácticas en el desarrollo para conseguir su mejora. Este conjunto de buenas prácticas definirán nuestro marco de calidad de referencia.

Después de que se haya identificado este marco de calidad de referencia, puede ocurrir que el equipo no sepa cómo encajar su aplicación en el día a día. Habrá que definir una estrategia de refactoring y una estrategia de mejora continua para las partes más pobres en calidad para mejorarlas progresivamente.

Llegados a este punto, el equipo comienza a estar listo para producir software de buena calidad. Ahora hay que ir mejorando esta calidad iterativamente e incrementalmente, pues el producto necesita seguir evolucionando y debe seguir prestando servicio al mismo tiempo.

Cliente

El cliente también percibe la calidad del producto, desde una dimensión muy diferente. La percibirá en las fases de fabricación donde más se involucre.

Si le entregamos análisis funcionales de calidad donde no solo describimos funcionalmente las features sino que identificamos casos límites que se dan en su negocio y le pedimos su implicación, entonces el cliente percibirá que se está haciendo un buen trabajo. Empleará esfuerzo en buscar la mejor solución a cada caso. Se empezará a discutir con el cliente si merece la pena desarrollar una parte específica y compleja de una feature teniendo en cuenta el coste de fabricación, el mantenimiento y la futura evolución.

La profundidad de las conversaciones ahora permite este tipo de decisiones. Se dejarán atrás las típicas discusiones entre cliente y proveedor de si algo entra o no en el alcance según el contrato.

Si en el reporte de pruebas de aceptación el cliente ve que hay un volumen de pruebas suficiente, que se prueban la mayoría de los casos y que se han modificado adecuadamente las pruebas de regresión del producto, entonces quedará confiado. No porque no vaya a surgir bugs en producción, sino porque los bugs que surjan no tendrán gran impacto en su negocio.

Cuanta mayor calidad perciba el cliente durante la fabricación y cuantos menos bugs surjan en producción, mayor confianza tendrá en el producto. Y cuanta más confianza tenga, más posibilidades de evolución en el producto verá.

Invertir en calidad es invertir en el largo plazo.

Empresa

Nuestra empresa requiere certificaciones de calidad para poder concursar a algunos contratos.

Cuando tu proceso de fabricación pasa una auditoría de calidad y compruebas que cumples con la mayor parte de los requisitos significa que vas por el buen camino, por dos motivos. Porque no tendrás que llevar una documentación paralela para justificar que cumples con el sistema de calidad. Y porque se evidencia que estás haciendo bien las cosas.

Los procesos que sigues y los activos que produces surgieron por pura necesidad en el intento constante de mejorar la calidad. Al surgir desde esta necesidad ya está madurado y aceptado por todo el equipo. Es más, el equipo no podrá dejar de hacerlo. Al haberse imbuido estos procesos y activos en tu proceso de fabricación es seguro que serán ágiles de aplicar y seguir, pues de lo contrario no serían del agrado de los desarrolladores y testers.

Mínimos de calidad

Un producto sin calidad no puede sobrevivir demasiado tiempo en el mercado ofreciendo un buen servicio. Según pase el tiempo el producto irá evolucionando y la entropía del código crecerá.

Si el producto se creó rápidamente para aprovechar una oportunidad de negocio seguramente la calidad no fue prioritaria. Si por el contrario se creó ya desde el inicio con calidad eso no te garantiza que la calidad se mantenga según va evolucionando. Para mantener la calidad se necesita hacer un esfuerzo y reservar presupuesto para ello. Cómo se reparte este esfuerzo a lo largo de la vida del producto es otra historia.

El equipo que creó inicialmente el producto va variando. Nuevas personas se incorporan y otras se marchan. El conocimiento que tienen las personas del producto tampoco es siempre el mismo a lo largo de su vida. Sin embargo se necesita asegurar un mínimo de conocimiento como para mantener y evolucionar el producto. Este conocimiento mínimo tampoco es siempre el mismo, pues el producto irá ofreciendo servicios cada vez más específicos del dominio, por lo que hay un descubrimiento incremental del dominio por parte del equipo.

Como vemos todas estas dimensiones van variando a lo largo del tiempo. Sin embargo, necesitamos agarrarnos a caracterizaciones invariables que nos permitan trabajar en una dirección correcta para garantizar la calidad.

Un coche ha sido ensamblado por piezas en una cadena de producción siguiendo fases bien definidas.

Si no tienes un proceso de fabricación bien definido entonces no podrás fabricar un producto de calidad. Cada fase de producción, activo producido y roles del equipo deben existir por ser necesarios, no porque un estándar de calidad lo requiera. Sabes que algo es necesario porque si lo eliminas de tu proceso estás dejando un agujero en la fabricación. Hace unos meses comenzamos a desgajar la arquitectura monolítica de nuestro producto en varios microservicios. Las nuevas features ya las desarrollamos usando este paradigma de microservicios. Sin embargo, la primera versión que creamos con esta arquitectura mixta fue un desastre. No habíamos puesto suficiente foco en el ensamblaje entre los microservicios y los componentes monolíticos. Lo que hicimos en la siguiente versión fue incluir en el proceso de fabricación una fase de ensamblaje, ubicándola tan temprana como fue posible. Apadrinamos este nuevo proceso de fabricación "assembly first". También identificamos un nuevo rol en el equipo: "ensamblador", al que asignamos tareas y responsabilidades específicas. Esto es solo un ejemplo de una fase que hemos identificado como necesaria por un cambio en la arquitectura del producto.

Las piezas del coche han podido comprarse a proveedores externos. Estos proveedores han validado el funcionamiento de cada pieza por separado. Tendrán máquinas que prueben y aseguren la calidad de cada pieza. Durante la fabricación el coche pasará sus pruebas de ensamblaje, pruebas de seguridad, pruebas de usabilidad, etc.

Se necesita probar por partes el producto. No es suficiente con tener pruebas de aceptación end to end. Es necesario tener pruebas a nivel de componente. El código de tests unitarios y de integración es tan importante como el código de las features del producto. Un producto con calidad debe tener más líneas de código destinado a probar el producto que las propias líneas de código de las features. Si no hay una buena cobertura de tests unitarios y de integración es un síntoma de que el código no ha sido ejecutado las veces necesarias. No puedes hacerte una idea completa de tu producto hasta que no lo hayas ejecutado miles de veces y hayas observado su comportamiento dinámico en ejecución. No hay otra forma de ver el comportamiento dinámico del software. Los análisis y diseños en papel lo soporta todo. Necesitarás emuladores y simuladores que ayuden a realizar las pruebas a nivel de componente y de integración. Harán el mismo papel que las máquinas para probar las piezas de un coche.

La volatilidad del software derivada de los cambios en los interfaces entre componentes y en los comportamientos de éstos hacen incluso más necesario estas pruebas a nivel de componente y a nivel end to end. Para poder garantizar este testeo es necesario que ya durante el diseño del producto se esté pensando en cómo probarlo. La arquitectura del producto se diseñará mirando desde varias perspectivas: funcionalidad, rendimiento, entorno en el que se desplegará el producto, testeo y _mockeo _de componentes, etc.

El coche se venderá ofreciendo una garantía por unos años. Si durante esa garantía o incluso fuera de ella surge alguna avería, lo llevas al taller, detectan la avería y la corrigen. A no ser que la avería sea muy grave, el precio será asumible. La avería puede estar localizada en alguna pieza concreta, en cuyo caso se pedirá un recambio al proveedor y se montará reemplazando a la pieza averiada en el coche.

Has puesto en producción tu producto y ya está ofreciendo servicio al cliente. De repente se identifica un bug crítico. Sin embargo, cuando lo analizas te das cuenta que es irresoluble o su resolución podría desestabilizar el producto. ¿Te imaginas llevando tu coche al taller y que el mecánico te diga que no tiene solución la avería o que no sabe cuánto va a tardar en resolverlo? Casos seguramente que los habrá, pero dudo que haya tantos como en el software.

El fabricante de un coche se plantea sacar un nuevo modelo el año que viene. Ya tiene identificadas las piezas que tiene que mejorar, como afectan estos cambios al ensamblaje, proceso de fabricación y pruebas. A ti el cliente te pide incluir una nueva feature o modificar una ya existente y como resultado del análisis concluyes que antes de hacer estos cambios hay que refactorizar la mitad de tu producto? ¡Es inconcebible para el cliente!

Si no sabes las limitaciones de tu producto entonces no tienes un producto. Vemos normal que el fabricante de un coche sepa sus limitaciones: velocidad máxima, resistencia a impactos, capacidad máxima de carga, etc. ¿Y tú ni siquiera sabes los casos del negocio que no cubre tu producto? Si no sabes estas limitaciones es que no has analizado a fondo ni tu negocio, ni tu modelo ni la codificación de tu producto. Y por supuesto no tienes una cobertura de tests suficiente como para haber levantado estas limitaciones incluso antes de ponerlo en producción.

Tu producto no puede tener asunciones en el código que no estén directamente relacionadas con sus limitaciones ni con la documentación técnica del producto. ¿Cuántas veces hemos visto tomar el primer elemento de una lista porque no nos encaja una colección con un solo elemento? Cientos de veces. O en la rama _else _tomar un objeto con datos por defecto sin ningún sentido. O no hacer nada y dejar un traza que quedará sepultada en algún inmenso fichero de log...

El cliente te hace una pregunta acerca del comportamiento de tu producto ante un caso concreto de su negocio. Preguntas al equipo y nadie lo sabe. Entras a analizar el código y tampoco puedes confirmar sin duda alguna su comportamiento. ¿Cómo es posible que suceda esto y con tanta frecuencia? ¿Te imaginas la misma situación en la que un cliente pregunta al vendedor de un coche y éste no sabe contestar? Vale, aceptamos que el software evoluciona muy rápidamente. Sin embargo, debes graduar la rapidez con la que evoluciona tu producto o si no el fracaso estará garantizado. Tu equipo debe asimilar esta evolución y necesitará tiempo para consolidarla.

Fijate que no he entrado en demasiados detalles técnicos. He puesto el nivel muy bajo y sin embargo apuesto a que la mayoría de productos no cumplen estos mínimos que garanticen su calidad.

Si una pieza de un coche se fabrica con defectos esto conlleva una repercusión económica pues ya se han fabricado 1.000.000 de unidades. En cambio el software tiene defectos y aún así sale a producción. No se tiene en cuenta el posterior coste cuando haya que corregir los bugs. La intangibilidad del software juega en contra. Esta intangibilidad influye en la falta de disciplina y rigor en la fabricación de software. Es cierto que los plazos tan justos y la presión por sacar tu producto condicionan. Y también es cierto que cuando no existen estas restricciones tampoco se tienen ni disciplina ni rigor.

Mejora contínua

La clave para recuperar la calidad de un producto es la mejora contínua. Más aún si el producto debe seguir evolucionando y prestando servicio. La mejora contínua consiste en ir haciendo cambios en el código aplicando buenas prácticas de modo incremental e iterativo.

Como vimos antes, un conjunto de buenas prácticas quedan agrupadas en un marco de calidad de referencia. Iremos definiendo y aplicando los marcos de referencia que vayamos definiendo. Cuando hayamos aplicado todo el marco, podremos definir otro nuevo marco incorporando nuevas buenas prácticas.

Será necesario definir al menos dos marcos de referencia en paralelo: uno para el código legado y otro para el código nuevo. Esto es así porque no todas las buenas prácticas del marco definido para el código nuevo podrán ser aplicadas debido a que tengamos diferentes versiones del lenguaje, porque no tengamos el mismo framework de desarrollo o porque el coste de aplicar todo el marco no sea asumible en ese momento.

Código legado

Los desarrolladores seniors realizarán la mejora contínua en el código legado. Ellos ya llevan trabajando tiempo con el producto y entienden el dominio, el modelo codificado y las features del producto. Sabrán qué uso hacen los usuarios de las features para poner el foco en las features que más valor aportan.

Aplicaremos diferentes técnicas para mejorar de modo incremental dependiendo de las características del código a modificar.

A menudo me he encontrado con implementaciones complejas de features intentando cubrir todos los posibles casos e implementando una lógica muy compleja por ello. Sin embargo, cuando lo pruebas no funciona ni en los casos más básicos y que con mayor frecuencia se dan. Para solventar esto podemos aplicar la técnica de simplificación de código. Esta técnica se podrá aplicar en varias situaciones. Si el código no implementa features importantes en el producto. O si su calidad es tan pésima que no es posible ni siquiera mantenerlo. O son features no visibles a los usuarios finales. O el código está aislado con respecto al resto del producto y casi no tiene dependencias.

La técnica de simplificación consiste en reducir todo lo que se pueda la complejidad del código y posteriormente aplicar sobre este código simplificado los marcos de referencia sucesivamente. Lo primero es analizar el código existente. Ver qué datos de entrada y de salida hay y cuál es su comportamiento dinámico. Este comportamiento no siempre podrá verse ejecutando el código ya que puede resultar un proceso muy lento. A no ser que sea muy crítico, lo evitaremos. En su lugar, habrá que inferir este comportamiento analizando el código. Después se volverá a codificar cubriendo los casos más representativos del negocio y dejando los casos menos comunes. Estos casos se registrarán en la documentación para no perderlos. Después se codificarán los tests unitarios y tests de integración para garantizar el funcionamiento del código modificado. Por último, se hará la documentación técnica a partir de este código.

Llegados a este punto no se ha recuperado el código en su totalidad. Sin embargo, lo importante es que se vuelve a tener el control sobre el código. En el caso de que surjan bugs seremos capaces de resolverlos en un tiempo y coste asumibles.

Hay riesgo en que se produzcan bugs relativos a los casos que no cubrimos durante la simplificación. Si se produjera alguno, consultaremos en la documentación si se refiere a algún caso no cubierto, lo corregiremos y actualizaremos la documentación. Paradójicamente rara vez que he aplicado esta técnica luego el usuario ha reportado bugs.

En la siguiente iteración de mejora iremos aplicando más buenas prácticas del marco de referencia actual o pasaremos al siguiente marco de referencia. Asimismo, se irán incluyendo más casos no cubiertos que estaban registrados en iteraciones anteriores.

Código nuevo

La mejora contínua en el código nuevo consistirá en ir aplicando progresivamente las nuevas buenas prácticas de los marcos de referencia. En este caso el objetivo principal es optimizar el proceso de fabricación del código nuevo para compensar el sobre esfuerzo y sobre coste por recuperar la calidad del código legado.

Es posible que caigamos en la obsesión de mejorar la calidad contínuamente. No es algo contraproducente si se establece un plan progresivo. Se puede mejorar indefinidamente siempre que analicemos su coste y beneficio, tanto a corto como a largo plazo. El equipo tiene que aprender a aplicar los nuevos marcos de referencia y esto requiere tiempo y esfuerzo.

Para suavizar esta obsesión viene bien hacer una retrospectiva. Remontarse al pasado y ver qué código se estaba produciendo, cómo era el proceso de fabricación, el volumen de bugs reportados por el equipo de testing, los bugs reportados por los usuarios o cualquier otro indicador que consideremos útil. Esto nos permitirá ver la sustancial mejora que hemos ido acumulando y que en el día a día no se percibe fácilmente.

Entre dos tierras

Puede ocurrir que una misma persona del equipo esté mejorando código legado y codificando nuevo código. Esta persona tiene entonces un gran desafío.

Cuando entra a modificar código legado en su mente estarán ambos marcos de referencia y percibirá claramente la calidad superior del código nuevo. Sin embargo sólo deberá considerar al marco de referencia del código legado y esto le creará frustración por no poder aplicar todas las buenas prácticas del marco de referencia del código nuevo. Por no poder dedicar todo el tiempo que quisiera, tirar a la basura el código legado y rehacerlo.

Por otro lado, tendrá esperanza en que tras varias iteraciones de mejora podrá recuperar la calidad deseada en el código legado. Son sensaciones contrapuestas muy interesantes de observar.

Conviene que varias personas codifiquen en código legado y en código nuevo. La apreciación de la calidad se verá reforzada.

Efectos

egún aumente la calidaddel producto, la importancia que el equipo asocie a la calidad también irá en aumento. Básicamente porque su día a día va mejorando. Cada vez hay menos estrés por tener que resolver bugs aprisa.

A medida que la calidad del producto mejora, la satisfacción del cliente aumenta y esta satisfacción es un feedback muy positivo para el equipo. El equipo ve que el producto que está desarrollando tiene buena acogida.

Una vez que el equipo ve la necesidad de desarrollar código con calidad, comienza a apreciar al código como el activo más preciado. El código ya no pertenece a quién lo hizo o modificó por última vez. Pertenece a nadie y a todos. Cada línea cuenta y es cuestionada. Si no se entiende que hace simplemente se elimina. ¡Cuántas veces vemos comprobaciones de variables !=null ! Ves el código y muy posiblemente nunca venga a null. Decides quitar esta comprobación que no hace más que empeorar la legibilidad del código y si tiene que explotar que lo haga. Ya saltará durante las pruebas. El objetivo es eliminar incertidumbre constantemente en la ejecución del código. El equipo quiere entender qué hace cada una de las líneas del producto. Parece obvio pero no lo es.

Cuando alguien del equipo entra a modificar un componente del producto y ve una parte con mala calidad advierte al resto, se analiza su gravedad y se registra como deuda técnica. Podrá ser recuperada esta deuda en ese momento o no, eso ya depende de la estrategia de refactoring definida y de la necesidad que haya. El código con buena calidad cohesiona al equipo. Todos reman en la misma dirección y colaboran en conseguir esa buena calidad y en recuperar la deuda técnica.

Algunas personas del equipo no quieren mejorar. Puede que no hayan visto la necesidad de mejorar. Puede que no hayan sufrido las consecuencias de tener mala calidad y que no les haya tocado resolver bugs sin apenas tiempo. O puede que directamente no quieran asumir el esfuerzo para codificar garantizando buena calidad. En este caso se produce un desequilibrio. Las demás personas que sí aprecian la calidad comienzan a ver que el código que hacen algunos no es de buena calidad. Su cultura ya no les permite dejar ese código así y lo tienen que rehacer. Comienzan los conflictos. Las personas que abogan por la buena calidad no quieren trabajar con los otros. El equipo está dividido y hay que tomar una decisión. Las personas que no se han adaptado a la nueva cultura deben dejar el equipo. Esa es la decisión.

Cuando se incorpora una persona nueva en el equipo cuesta conseguir que se acomode a nuestra cultura. Esta persona cuestiona las buenas prácticas definidas y no sabe el motivo de por qué se definieron. No puede comparar el código que actualmente se está creando con respecto al código legado. Una buena aproximación es que esta persona participe en alguna iteración de mejora de un código legado sencillo. Otra aproximación más radical es que participe en la corrección de bugs. Sin embargo estas aproximaciones tienen su riesgo y habrá que evaluarlo convenientemente antes de aplicarlas.

Capacidad máxima viable

Desde hace años practico wing tsun. Como arte marcial requiere tiempo y dedicación adquirir destreza. Requiere muchas repeticiones de movimientos corporales con plena atención y conciencia. Durante la práctica pude observar como tiendes a querer ir más rápido de lo que puedes, en detrimento de la calidad de tus movimientos y provocando una excesiva rigidez corporal. Incluso me observé haciendo esto con una técnica recién aprendida. Si aún no tienes adquirida la biomecánica de la técnica difícilmente podrás imprimir velocidad en la ejecución.

Observate y sé consciente de tus limitaciones al codificar. Si no eres capaz de garantizar el correcto funcionamiento de un código simple, no lo compliques aún más. No está a tu alcance. A tu ego le gustará codificar con flujos y estructuras de datos complejas pero el resultado final será nefasto. Céntrate en ir poco a poco, adquiriendo destreza en codificar según tu nivel. Según vayas dominando ese nivel, podrás ir codificando cosas más complejas.

La maestría está en codificar una solución simple para resolver un problema complejo. La simpleza de la solución obviamente será relativa a la complejidad del problema.

Calidad en prototipos

No es lo mismo la calidad de un producto que presta un servicio 24x7 que la calidad de un prototipo que demostrará la viabilidad de una idea. Tu producto puede incluir en algún momento un prototipo.

Lo más seguro es que el modelo codificado en el prototipo se haya simplificado y no cubra todos los casos del dominio. O que no tenga ni tests unitarios ni tests de integración. O que la integración con el resto de componentes no sea la más idónea técnicamente sino la que menos modificaciones requería en el resto del producto. Las pruebas de aceptación pueden ni existir o no ser completas. Lo mismo puede ocurrir con la documentación técnica del prototipo.

Puede ocurrir también que el desarrollo de este prototipo no lo haya hecho el equipo que desarrolla el producto. Corría prisa tener el prototipo cuanto antes y el equipo del producto ya tenía en su roadmap varias versiones con alcances comprometidos con el cliente.

No obstante, el objetivo del prototipo se cumplió. Se minimizó con estos recortes su coste de fabricación y se acortó su desarrollo.

El problema viene cuando se quiere que este prototipo también de el mismo servicio 24x7 que el producto sin modificar nada de éste. Sin analizar sus consecuencias el prototipo se pasa a producción y ocurre lo esperado. Surgen demasiados bugs cuya resolución es muy costosa o incluso imposible. No quedará otra opción que refactorizar este prototipo y recuperar su calidad para igualarla a la calidad del producto.

Si la compañía decidió que lo desarrollara otro equipo diferente al equipo del producto, entonces habrá que dedicar esfuerzo en hacer la transferencia del desarrollo al equipo del producto. Esto no será una tarea sencilla ni desprovista de conflictos que se verán agravados si los equipos son de departamentos diferentes.

Un caso extremo es cuando el prototipo pasa a producción ofreciendo servicio sin haberlo refactorizado para subir su calidad y el producto incluye nuevas features que afectan a este prototipo. El modelo del prototipo no encaja con el modelo del producto. Ahora estás obligado a refactorizar el prototipo y asumir este coste inesperado.

En la estimación del coste de fabricación del prototipo habrá que incluir el coste de refactorización para recuperar su calidad y el coste para hacer la transferencia entre equipos.

Define un proceso de fabricación a medida para el desarrollo de prototipos. Así, cuando se desarrolle un prototipo sabrás qué fases y activos del proceso de fabricación del producto no se han producido. Al equipo le costará seguir este proceso de fabricación a medida. Le costará dejar sin codificar tests unitarios o de integración, por poner un ejemplo. Incluirá incertidumbre que puede materializarse en un sobre coste durante la fase de demostración del producto.

Mantenimiento de la calidad

Estamos inmersos en una mejora contínua e incremental de la calidad del producto. Ponemos especial foco en recuperar la calidad del código legado dedicando mucho esfuerzo. Sin embargo, no debemos pasar por alto cómo se produce el nuevo código. Recordemos que las personas del equipo más seniors están recuperando el código legado, mientras que los más juniors están codificando código nuevo según el marco de referencia de calidad definido.

Hay un riesgo en que el código nuevo también sea de mala calidad, a pesar de tener definido el marco de referencia y la haber redefinido los procesos de fabricación. Para mitigar este riesgo incluiremos auditorías de código que nos levanten cuanto antes no conformidades y sugerencias de mejora en el código.

Es muy frustrante ver que se va recuperando el código legado y sin embargo el código nuevo sigue siendo de mala calidad. Sobre todo, es frustrante para las personas que están haciendo un sobreesfuerzo con el código legado.

Otro aspecto a mantener es la cultura sobre la calidad. Para facilitar esto ayuda que el equipo sea estable, sin demasiada rotación de personal. Al fin y al cabo la cultura la forman, la definen y la mantienen las personas del equipo. Si no se tiene una rotación de personal baja, entonces habrá que dedicar más tiempo a que las nuevas personas que se incorporan conozcan y apadrinen nuestra cultura.

La calidad debe derivarse del proceso de fabricación. Sus fases de producción, los activos generados, los roles y competencias identificados dentro del equipo te llevan inevitablemente a fabricar un producto de calidad. Una vez que esto esté establecido la calidad se mantendrá. El equipo cogerá ritmo y seguirá este proceso de fabricación en cada versión del producto. Además, tendrá un constante feedback positivo porque Operaciones apenas reportará bugs del producto. Ahora estarán seguros de que lo que fabrican tiene calidad.

Sin embargo, la compañía ha de pensar bien si realmente quiere lograr una buena calidad. Ahora ya no valdrá dar más peso a los plazos de entrega o a aumentar el beneficio en detrimento de la calidad. El equipo no sabrá fabricar de otro modo a menos que se redefina otro proceso de fabricación para conseguir este nuevo objetivo. Y seguir este nuevo proceso llevará tiempo. Incluso, algunas personas del equipo se negarán a trabajar así.



Deja una respuesta

Subscríbete::About