Curso de técnicas de Refactoring y Clean Code
Con este curso de refactoring y clean code aprenderás a detectar código sucio y a aplicar técnicas y...
Te aclaramos qué es la deuda técnica, un concepto que no es nuevo, pero vuelve a estar presente en el ámbito de desarrollo, y cómo evitarla en tu empresa.
Si bien el concepto de deuda técnica tiene casi 30 años, el avance y popularización de las metodologías ágiles como XP o Scrum han hecho que durante los últimos 5 o 10 años, se escucha de forma más frecuente, en particular en el ámbito de desarrollo de software y empresas vinculadas con las TICs. A pesar de que esta idea es ampliamente usada, la mayoría de las personas no saben realmente lo que es o tienen una idea equivocada.w
En general la gente entiende como deuda técnica como algo relacionado a escribir código de mala calidad o pobre. Si este fuera el caso, simplemente con tener en cuenta buenas prácticas de desarrollo, escribir código limpio desde el comienzo y aplicando patrones de diseño este problema no se vería.
Otro caso en donde se ve una deuda técnica es en la documentación, donde se hace una mala interpretación de la sección del Manifiesto ágil que dice Software funcionando sobre documentación extensiva, en ninguna parte de esta oración dice NO documentación, pero a veces por gusto personales, otro por prioridades y otras porque no se ve el valor en ello, existe escaza o nula documentación. Acá se entiende la documentación como todo texto y/o imagen que aporta valor para entender el problema. Un buen comentario que explique el contenido en un commit, un comentario antes de una función o un gráfico de flujos del sistema son ejemplos de documentación valida.
Otro caso es cuando se está bajo presión por malas estimaciones y con la necesidad de entregar rápido nos llevan a que buenas prácticas relacionadas a calidad, test unitarios por ejemplo son dejadas de lado.
La pregunta que nos viene entones a la mente es ¿Qué es entonces la deuda técnica?
Toda actividad a gran escala produce cierta cantidad de desperdicios industriales, ya sea los trozos de madera que sobran en una carpintería o el agua son azufre en las minerías a cielo abierto. Todas generan estos subproductos durante el proceso de manufactura de sus productos. En la industria del software, estos desperdicios son las lo que conocemos como deuda técnica.
Antes de seguir con ejemplos y para responder mejor a esta pregunta, primero tenemos que ver su origen. El termino fue acuñado por Ward Cunningham, que entre otras cosas fue quien creó la primera wiki y los primeros patrones de diseño junto con Kent Beck. Ambos fueron parte del equipo que terminó creando el Manifiesto Ágil.
En 1992, Cunningham usó el termino como una analogía de una deuda financiera. “Con dinero prestado, tu puedes hacer algo antes de lo que lo harías de otra forma, pero luego y hasta que devuelvas el dinero estarías pagando intereses. Pensé que prestar dinero era una idea, apresurar el software para obtener experiencia con él era una buena idea, [..] pero eventualmente y a medida que aprendieras cosas sobre el software, pagarías el préstamo haciendo un refactoring del programa para que refleje la experiencia adquirida.” Acá vale la pena agregar también que “No hay que confundir deuda técnica con escribir mal código o pobre desde un punto de vista técnico (al menos no de forma intencional). Uno siempre debe escribir código que refleje nuestro entendemos actual del problema, aun si este es parcial”. Por lo tanto, diremos que es un desacuerdo entre las necesidades que tiene el negocio y como fue desarrollado el software
Entonces, la deuda técnica pasa a ser algo que surge de forma natural, como consecuencia de los diferentes procesos, cuando escribimos código para un problema que no entendemos del todo o que cambian los requisitos con el tiempo. En una metodología que se ve un buen manejo de la deuda técnica es en TDD. En esta, el proceso consiste es crear una prueba para cumplir con el requisito, escribir un código simple para pasar la prueba. Por último, se pasa a la etapa de refactoring para que el código sea de calidad.
Por lo tanto, la deuda técnica es más bien una propiedad interna del sistema y no algo visible, algo similar a lo que pasa con la calidad. Una forma de ver en que parte de nuestros proyectos se encuentra, es ver los mismos utilizando un cuadrante mágico comparando visible/invisible y valor positivo/negativo:
Basándonos en el gráfico anterior, tenemos que invertir tiempo en remover algo que es invisible y tiene un valor negativo de nuestro sistema y que es lo opuestos de lo deseado con patrones de diseño o una buena arquitectura del sistema.
La deuda técnica puede aparecer de diferentes formas u orígenes, pero en los últimos tiempos los expertos coinciden en que hay dos grandes categorías para agruparlas: deliberadas o inadvertidas.
Deliberada: También llamada activa o intencionales, aparecen cuando el equipo o la organización dejar de lado buenas prácticas para obtener un resultado anticipado o TTM (time to market) por sus siglas en inglés.
Inadvertida: También conocidas como pasivas, accidentales o desactualizados, son las que aparecen cuando nuestro código necesita mejoras con el tiempo. Bien puede ser por una mala elección de diseño o una degradación que se dio con el tiempo y al ir agregando nuevas funcionalidades o usuarios al sistema.
Un caso de deuda deliberada visible puede ser un código que procesa un arreglo de objetos y obtiene un promedio de sus valores, pero no lo hace de una forma eficiente, esto nos permite liberar la funcionalidad rápido y en próximas iteraciones corregir el problema.
En otros casos puede ser de forma inadvertida, por una lineamientos poco claros o políticas que favorecen la documentación para que el próximo que se enfrente con un código sepa para que fue pensado y como soluciona el mismo ese problema.
Como todo prestamos, la deuda técnica a medida que va pasando el tiempo genera más y más intereses. En este caso, los intereses lo vemos en el hecho de que cada vez tenemos menos tiempo para liberar nuevas funcionalidades y cada vez pasamos más tiempo corrigiendo problemas recurrentes. Además, esto también abre más la puerta para introducir nuevos defectos.
Podemos tener técnicos consultando a otros para saber cómo se resolvía un problema que sucedió hace 1 mes porque no existe un a wiki o KB para consultar.
También podemos tener un problema de escalabilidad, si parte de nuestro sistema es ineficiente, frente a un gran volumen de datos puede resultar en un problema que termine con todo el sistema caído.
Por último, tenemos el problema de la confiabilidad del equipo y del sistema. Un producto que cada vez anda más lento, que tiene problemas extraños desde el punto de vista del usuario. Desde el punto de vista de la gerencia, es una baja en la confianza del encargado del producto y del equipo.
El costo en horas que lleva una refactorización del código. No solo por el tiempo de diseño, sino también el esfuerzo que le lleva a la persona ponerse en el contexto del problema que quiere resolver y las innumerables horas de arreglos de todo tipo que se tuvieron que ir agregando desde la primera versión hasta este momento.
Una buena medida es cuando un grande del tiempo planificado del equipo se gasta en tareas relacionados a problemas en el código. Como todo umbral no hay un número mágico, pero podemos decir que si más del 30% de nuestro trabajo es de este tipo es tiempo de analizar lo que está pasando antes de que las cosas se terminen de salir de control.
Además de los tipos de tareas que se realizan en cada iteración, podemos contar con diferentes medidas para obtener información interna del proceso.
Hay una frase muy común y usada que dice Lo que no se define no se puede medir. Lo que no se mide, no se puede mejorar. Lo que no se mejora, se degrada siempre (Lord Kelvin). Cuanta sabiduría en tan pocas palabras, y que acertadas para este tema que estamos viendo. Ahora, en las partes anteriores estuvimos definiendo el qué es, ahora tenemos que ver el cómo. Existen varias métricas que podemos usar, pero veamos las que aportan más valor para este tema.
Defectos: Como desarrolladores debemos tener un estricto seguimiento de nuestros bugs. Tanto los resueltos como los que siguen ahí, los que siguen nos dan una idea de cuánto tiempo debemos invertir en solucionar un problema mientras que los resueltos nos dan una idea de que tan bien estamos mejorando nuestro sistema.
Calidad en el código: A diferencia de los bugs, la calidad del código nos habla de lo que está por debajo de la superficie de nuestro sistema. Realizar análisis estático del código para ver su complejidad ciclomática
, árboles de profundidad de herencia
o que no se respetan los estándares y convenciones de código.
Adueñarse del código: A medida que nuestros equipos crecen es más probable que aparezcan deudas técnicas no intencionales. Todo el equipo debe tener una actitud activa sobre el código. Los gerentes tienen que saber quién está trabajando en que sección del sistema en caso de un problema y el equipo de desarrollo se debe hacer responsable de dicho código, aun si el mismo es heredado.
Cohesión de código: Buscando que nuestro sistema tenga una alta Cohesión y un bajo acoplamiento entre sus partes nos permite saber que el código está más auto contenido y por tanto es más fácil elaborar pruebas individuales para cada parte.
Puntos calientes: Buscar lugares de nuestras soluciones que tiene mucho trabajo de reescritura o cambios. Debemos tener un cuidado especial en estos sectores ya que pueden estar evidenciando un área que puede necesitar una reingeniería o refactorización para mejorar.
Como en toda industria, debemos minimizar nuestros desperdicios durante el proceso de desarrollo de software. Primero tenemos que alinear nuestro backlog o lista de tareas para que en cada iteración haya espacio para trabajar en reducirla, puede ser tiempo de rediseño, o de generalizar y elaborar estándares de diferentes procedimientos.
Después es importante revisar periódicamente nuestras definiciones de cuando una tarea esta lista para ver si no estamos apurando el proceso a costo de un mal diseño.
Otro punto para evitar la deuda técnica es generar pruebas automatizadas, estos permiten a mediano y largo plazo generar un conjunto amplio de validaciones del sistema y contar con una gran cobertura del código reduciendo riesgos.
En SCRUM
tenemos la posibilidad de hacer sprint retrospective para poder dedicar parte de la revisión a posibles problemas de diseño que se hayan encontrado, también es un buen momento para consolidar todo el aprendizaje y volcaron nuevamente al código durante los siguientes sprint. Si no estamos dentro del paradigma de SCRUM, podemos utilizar la herramienta de post mortem que nos puede ayudar a encontrar posibles deudas técnicas.
Hablar de metáfora nos permite usar un marco común para entender un problema que es invisible dentro de los sistemas informáticos. Si bien está ampliamente aceptada, no está exenta de problemas. Por ejemplo, a nadie le gusta deber nada y menos tener que pagar las deudas de otras personas.
Hoy en día hay un montón de gente que libera software de forma rápida o apresurada y aprenden cosas, pero nunca agregan esos aprendizajes al programa. En la metáfora del préstamo es como si nunca pagáramos la deuda y entonces en algún momento todos nuestros ingresos (trabajo semanal) se dedicará a los recargos.
Debemos estar constantemente monitoreando la misma para no perder de vista nuestro objetivo dentro de la organización.
No debemos desesperarnos por las posibles carencias que tenga nuestro sistema o la cantidad de esfuerzo que debemos invertir. Debemos saber dónde estamos parados para poder mejorar.
Toda industria produce desperdicios durante su proceso de manufactura, en general se llaman desperdicios. Es un subproducto del software que no se puede evitar, por lo tanto, no es mala o buena. Lo malo es lo desconocido, lo que no se tiene seguimiento, lo que no fue planeado o lo que no fue manejado correctamente. Podemos poner nuestros esfuerzos en reducirla y no dejar que la misma crezca, pero sepamos que siempre va a estar ahí. Entonces es mejor que cuando pase, sea por una decisión consientes de parte del equipo para poder tener control de esta.
También te puede interesar
Con este curso de refactoring y clean code aprenderás a detectar código sucio y a aplicar técnicas y...
Aprende con nosotros qué es Scrum, cuál es su filosofía y las herramientas que utilizamos en la...
Aprende buenas prácticas con este curso de Clean Code para ser mejor desarrollador y crear mejores aplicaciones con...