
Cada producto evoluciona de una manera misteriosa. Ni siquiera un equipo experimentado puede predecir cada giro del ciclo de vida del producto. Las características simples pueden transferirse a flujos de trabajo monstruosos con múltiples condiciones. Algunos escenarios secundarios desarrollados rápidamente pueden convertirse en los más utilizados. Incluso la popularidad del producto puede generar problemas de rendimiento inesperados. Y es completamente normal adaptar el software a las necesidades del mercado. La única forma de tener un producto confiable y predecible es reservar algo de tiempo para solucionar la deuda técnica y proporcionar un proceso de refactorización adecuado.
Es mejor incluir algunas definiciones de términos en este artículo. La deuda técnica, o deuda tecnológica, son los compromisos acumulados en la base de código, que pueden ocurrir durante el desarrollo rápido u otras fluctuaciones. El proceso de refactorización tiene más que ver con la mejora del producto en general. Puede implicar actividades relacionadas con el rendimiento, una mejor estructura del código y la simplicidad de la solución. Sin embargo, a veces estos dos conceptos pueden estar muy cerca. Por ejemplo, unas pocas características llenas de deuda técnica pueden requerir una refactorización adecuada de todo el módulo para solucionar el problema de una vez por todas con nuevas ideas y una reimplementación.
Y aquí está el truco. En general, los buenos desarrolladores de software tienen muchas ideas para mejorar el producto. “Está bien, podríamos ajustar algunas cosas durante esta función”. “Oh, eso no es tan importante, pero sería bueno arreglar esto en este módulo secundario”. Aun así, es crucial permitir que los miembros de su equipo tengan la oportunidad de mejorar la base de código, ya que ayuda a construir equipos realmente involucrados. Sin embargo, en este artículo, me gustaría revelar el proceso de refactorización desde la perspectiva de un gerente. Los ejemplos anteriores tienen un problema: pueden ser opacos para todo el equipo, excepto para los desarrolladores. Si bien el control de calidad y los gerentes tienen su plan para lanzar un software adecuado y estable a tiempo, algunas mejoras ocultas pueden crear giros inesperados y nuevas pruebas nerviosas durante el lanzamiento. O incluso nuevos errores en producción si, durante la etapa de regresión, algunos cambios no documentados pasan desapercibidos. Por lo tanto, las mejoras de código son necesarias, pero deberían ser manejables.
La solución es compleja. Agile es nuestro mejor aliado porque los principios y rituales comunes de las metodologías de desarrollo ágiles cubren los puntos problemáticos. Es necesario:
Por preparación me refiero a la comunicación entre los miembros del equipo antes de la iteración destinada a definir el alcance de la iteración, especificar los requisitos, descomponer las tareas, estimar los esfuerzos y priorizar los elementos de trabajo futuros. El proceso de planificación está conectado con el alcance resultante de la iteración. No todas las tareas preparadas pueden incluirse en la iteración.
Vamos a profundizar en cada tema.
La forma más sencilla para cualquier desarrollador de generar una cartera de deuda técnica es utilizar etiquetas "Por hacer" en el código fuente. Más adelante, podría buscar en la base de código, mejorar algo y enviar solicitudes de incorporación de cambios para su aprobación. Pero eso no es suficiente. No ayuda a los miembros del equipo a proporcionar una planificación adecuada y a estar seguros del alcance de la versión.
La mejor alternativa a usar “Por hacer” es establecer un proceso para crear las tareas para cambios futuros. Si el desarrollador encuentra algún punto problemático potencial o tiene una idea para mejorar la base de código, debe crear un elemento de trabajo en el sistema de tickets (Jira, Azure DevOps o cualquier sistema que use el equipo). Sería excesivo exigir a los ingenieros que proporcionen una descripción detallada de su idea para cada miembro del equipo, pero la explicación debe ser lo suficientemente clara para que el líder del equipo comprenda el punto clave y el alcance de los cambios. Esto cubre el primer paso: cómo podemos crear una lista de tareas potenciales y proporcionar una descripción de alto nivel de los cambios futuros.
El segundo paso es hacer que todo el mundo lo entienda. Esta tarea podría estar a cargo del líder del equipo de desarrollo, el gerente de lanzamiento o el gerente de producto, según su cualificación. El resultado debería brindar los siguientes detalles:
Si el elemento de trabajo tiene respuestas a todas estas preguntas, ayuda a mitigar posibles problemas en el futuro. Sin embargo, tener un backlog por sí solo no es suficiente para una refactorización manejable. Debe planificar los posibles cambios, y estos deben ser una parte constante de su proceso. Por supuesto, se enfrentará a la presión de las características comerciales y las demandas del mercado, donde la tentación de omitir tareas técnicas es alta. Pero sin un mantenimiento adecuado, se enfrentará a problemas aún mayores en el futuro.
La recomendación para el proceso de backlog técnico es:
En cada iteración, el equipo debe reservar tiempo para mejoras técnicas.
Si hay alguna idea de mejora, debe formalizarse como un elemento de trabajo con una descripción adecuada.
Los elementos de trabajo deben participar en el proceso de preparación y ser discutidos por todo el equipo hasta que se identifiquen todos los beneficios y riesgos y se recopilen las estimaciones de todos los miembros del equipo.
Los elementos de trabajo se deben planificar en iteraciones ágiles de acuerdo con sus estimaciones.
El equipo debe ser consciente del posible volumen de deuda técnica en la iteración. El tiempo reservado se puede aumentar si es necesario, pero nunca debe ser inferior a la cantidad habitual. Esto ayuda a alentar a los ingenieros a crear nuevas tareas en el backlog y priorizarlas. Todos saben que sus sugerencias se pueden implementar y que el backlog se reducirá algún día, en lugar de convertirse en una enorme lista desmoralizante.
A veces, las tareas de deuda técnica pueden revelarse durante la discusión y la estimación, mientras que el equipo se enfrenta a obstáculos inesperados que hacen que la realización sea menos fiable y flexible. Por ejemplo, puede darse cuenta de que hay características similares y crear una nueva solo agravaría la base de código. Pero esas características no contienen la funcionalidad empresarial requerida en las nuevas. Y es mejor crear un servicio unificado que conecte todas las características similares para simplificar el mantenimiento en el futuro. Aun así, este cambio puede afectar y desestabilizar las características antiguas y ahí radica el desafío. Tal vez haya una manera de desarrollar nuevas características de forma económica y hacer la vista gorda ante las imperfecciones. O tal vez ahora sea la mejor oportunidad para crear un servicio unificado mientras solo hay unas pocas características similares. Lo más importante es establecer un proceso que ayude a los miembros del equipo a tomar una decisión basada en hechos revelados y estimaciones adecuadamente elaboradas. Es fundamental tener un sistema que evite situaciones en las que tales decisiones deban adoptarse durante la fase de implementación en un backlog comprometido.
Si las etapas de iteración funcionan bien, la divulgación de dichos momentos se producirá automáticamente mediante un proceso de preparación y planificación adecuado. Existen algunas reglas y pasos básicos que podrían proteger al equipo de obstáculos inesperados en la mayoría de los casos:
Los elementos problemáticos del backlog se pueden descomponer en tareas independientes y planificarse según las prioridades. Las decisiones sobre la estrategia de implementación pueden quedar en manos del responsable de la versión, según los riesgos y los plazos. Pero este enfoque ayuda a documentar todas las decisiones. Incluso si la tarea de deuda técnica se pospuso, se agrega al backlog. Más tarde, estas tareas deben revisarse y programarse. Este proceso soluciona los escenarios en los que se olvidan algunas ideas buenas y necesarias durante una iteración agitada.
Aun así, incluso con una cartera de deuda tecnológica bien gestionada y un proceso de preparación y planificación eficaz, es posible encontrarse con obstáculos inesperados y que consumen mucho tiempo durante el desarrollo. Los productos de software pueden ser complicados, especialmente antiguos o con una gran cantidad de funciones.
El uso de prácticas ágiles ayuda a recopilar información de forma temprana y tomar decisiones adecuadas. Una de las soluciones más sencillas son las reuniones diarias.
Si un ingeniero se enfrenta a algún problema, debe plantearse durante la reunión y analizarse más adelante. Cada obstáculo es único y puede consumir distintas cantidades de tiempo. No importa si el cambio se implementará en la iteración actual, en lugar de ser una característica "agradable de tener", o si requiere una revisión completa del alcance de la iteración. El problema debe crearse como una tarea de deuda técnica típica en el sistema de seguimiento, descomponerse y describirse como cualquier otra tarea similar en artículos anteriores. La coherencia es la clave y el equipo debe saber cómo manejar estas situaciones.
Todos estos métodos pueden parecer una forma adicional de robarle tiempo a todo el equipo con burocracia inútil. Y podría ser así si la ausencia de reglas estrictas y claras no creara tiempos difíciles para todos. Está bien no seguir estas recomendaciones en proyectos de corto plazo o en la etapa de producto mínimo valioso (MVP). Sin embargo, trabajar en producción con responsabilidades de calidad y productos grandes requiere un sistema de procesos internos bien definido. Repasemos las objeciones más comunes.
Y es verdad. Describir tus tareas en lenguaje natural a veces puede ser más difícil que corregir el código. Pero aquí tienes algunas soluciones:
Quizás, pero depende de la explicación. La prioridad es la descripción de lo que podría salir mal y qué funcionalidad podría desestabilizarse. Sin embargo, es útil escribir sobre el impacto del cambio porque ayuda a identificar posibilidades y escenarios adicionales. Además, incluso las ideas más profundamente técnicas podrían describirse en oraciones simples utilizando lenguaje natural. Si no es así, puede que haya algo incorrecto en la idea en sí, y eso podría ser un riesgo potencial: se debería reconsiderar toda la propuesta.
Simplemente escribe algo como:
“El método “XXX” consume demasiada RAM en cada llamada. Crear una caché adicional para este método ayuda a reducir el consumo de RAM y a acelerar todas las API. El método utiliza datos que cambian con poca frecuencia, basta con eliminar la caché al reiniciar. Los cambios son seguros, pero pueden afectar potencialmente las siguientes funciones: XXX, XXX, XXX…”.
En algunos casos, esto sería suficiente. En otros, esta sugerencia puede desencadenar la discusión, porque el ingeniero podría olvidar alguna funcionalidad antigua pero que todavía se utiliza y en la que este caché podría causar problemas. Durante el proceso de preparación, se revisará la idea y el equipo encontrará un compromiso.
La estabilidad y la fiabilidad son mejores que unas pocas mejoras porcentuales en el tiempo de ejecución de algunas funciones. Nadie se sentirá decepcionado por perderse un posible aumento del rendimiento, pero es fácil empañar la reputación de un producto.
La idea es optimizar los procesos y ayudar a evaluar los riesgos. Los ingenieros deben tener la oportunidad de mantener la base de código y proporcionar algunas mejoras. Para las cosas que son pequeñas y no desestabilizan todo el producto, es posible crear elementos de trabajo agregados que se pueden completar durante la iteración. Estas tareas aún deben revisarse como solicitudes de incorporación de cambios, pero no es necesario anunciarlas formalmente al equipo.
Las mejoras constantes de los productos son fundamentales para el negocio y ayudan a preservar la calidad general. Si mantiene la deuda técnica y las nuevas ideas en el estante, se quedará con un producto obsoleto y pronto tendrá dificultades para encontrar ingenieros expertos para mantenerlo.
Por otro lado, estas tareas compiten con las características de negocio y otras ideas que pueden impulsar a las empresas hacia nuevos horizontes. Estas recomendaciones sobre la cartera de tareas técnicas pueden ayudar a revelar y evaluar la importancia de estas tareas no solo para los miembros del equipo sino también para las partes interesadas. Ayudan a presentar estas ideas en lenguaje natural y a conservar y proteger el tiempo para la implementación. Esto supone una carga para los ingenieros con acciones adicionales, pero al final ayuda a todo el equipo a entregar productos confiables y de alta calidad. Y la responsabilidad de un gerente es elegir el instrumento o la política adecuados para mantener este proceso.