7i_GPS-T04-Técnicas-ArquitecturaYDeudaTécnica¶
Arquitectura y diseño ágiles y la deuda técnica Gestión de Proyectos Software¶
Arquitectura y diseño ágiles y la deuda técnica Gestión de Proyectos Software
Contenidos¶
- Arquitectura y diseño de software
- Una perspectiva ágil de la arquitectura de software
- Talleres de diseño ágil
- Talleres de documentación de la arquitectura del sistema
- La deuda técnica
¿Construcción de software?¶
- Plantear que el desarrollo de software es análogo a la construcción de edificios (el arquitecto crea los planos y los albañiles construyen el edificio) es una mala metáfora que no resulta útil
- El software no se construye (ni se fabrica), se diseña
- La construcción debe ser automática gracias al compilador y los pipelines de integración y despliegue
- Las casas no suelen cambiar sustancialmente una vez se han construido, y los cambios que se hacen (p.ej., reformas) son poco frecuentes
- El software puede cambiar radicalmente y los cambios hoy en día son muy frecuentes (incluso diarios)
- El software no se construye (ni se fabrica), se diseña
¿Qué es la arquitectura de un sistema software?¶
- La arquitectura de un sistema software es una propiedad del mismo, no una propiedad de su documentación
- La podemos documentar, podemos planificarla inicialmente y discutirla, pero la arquitectura real será la de aquello que finalmente creemos
- Corolario 1: la arquitectura es dinámica
- Puede cambiar con cada línea de código añadida o quitada
- Evoluciona conforme se programa
- Corolario 2: los diagramas y documentos no son el diseño real, el código fuente es el diseño real
- Aunque esto no significa que todo lo que nos importa de la arquitectura se pueda deducir del código fuente
Por lo tanto...¶
- La arquitectura de un software se “cultiva” día a día conforme se programa
- Un supuesto arquitecto de software que no está en contacto con el código fuente no está en contacto con la arquitectura real
- Se les ha llamado “arquitectos de PowerPoint”, “arquitectos de torre de marfil” o “arquitectos astronautas” (tan lejos del código que igual podrían estar en el espacio)
¶
Arquitectos astronautas¶
- Los arquitectos astronautas no tocan el código y no pueden detectar cuándo este se degrada ni ayudar a corregir esta degradación
- Llega un punto en que los programadores ignoran a los arquitectos astronautas, porque hace mucho tiempo que estos últimos no saben casi nada sobre la arquitectura real del sistema
- Los arquitectos astronautas crean grandes piezas de inventario (diseños grandes y muy detallados)
- Desperdicio cuando hay que cambiarlos
- Dificultan trabajar en lotes pequeños
¿Pero diseñamos y documentamos la arquitectura o no?¶
- El diseño por adelantado está bien
- La documentación arquitectural está bien
- Siempre que recordemos que
- La arquitectura diseñada inicialmente puede mejorarse
- La arquitectura diseñada inicialmente debe concretarse
- Los arquitectos tienen que tocar el código
- El diseño debe ser ágil
Talleres de diseño ágil¶
Talleres de diseño ágil
Talleres de diseño ágil¶
- Se pueden tener talleres de diseño al comienzo de la construcción de algo, y luego just-in-time cuando el equipo lo considere útil
- Participa todo el equipo (o todos los equipos involucrados)
- Se diseñan los elementos a implementar en los próximos sprints, o la arquitectura global del sistema, según dónde estemos en el proyecto
- No para especificar cómo va a ser
- Sí para discutir cómo empezar (luego evolucionará)
Talleres de diseño ágil¶
- Se modelizan
- Interfaces de usuario (importante)
- Algoritmos e interacciones críticos (p.ej., con diagramas de actividad y autómatas finitos UML)
- Entidades importantes y modelos de datos (p.ej., con diagramas de clases UML)
- Vistas de componentes y conectores
- Etc.
- Al principio del proyecto, es importante modelizar en horizontal y superficialmente
- Un poco de todo, diagramas que den una visión global
- Pero puede ser interesante tomar algunas características que sean importantes o complejas y modelizarlas más en profundidad para explorar su problemática
Talleres de diseño ágil¶
- Según el número de participantes, suele funcionar bien tener grandes pizarras (o algo grande donde se pueda escribir)
- Cubrir todas las paredes de la sala con algo donde se pueda escribir no es descabellado
- El software tipo CASE o de diseño de UML puede tener su utilidad, pero no en un taller de diseño
- Lo que se busca es facilitar la colaboración, y esta clase de software no ayuda con esto
- El formato taller permite discutir
- Uno de los valores principales de un diagrama es que permite discutir y probar alternativas mientras se crea
- Hacemos diagramas como soporte de la discusión sobre el diseño
Talleres de diseño ágil¶
Talleres de diseño ágil¶
- Los modelos que hacemos en estos talleres no son especificaciones
- Los diagramas resultantes serán una inspiración, esbozos y guías, no una especificación
- El código será el diseño real
- El diseño evolucionará conforme se programa y se aprende más del problema
- La documentación de diseño detallada se puede crear después de que el código se haya completado si hace falta
- Hay que tomar fotos de las pizarras y compartirlas con todo el mundo
Talleres de diseño ágil¶
- En un proyecto pequeño se puede avanzar bien sin talleres de diseño (aunque no sin diseño)
- Su valor aumenta conforme crecen los proyectos
- La integridad arquitectural de un sistema requiere que los desarrolladores tengan ideas compatibles y coherentes entre si
- Los talleres de diseño contribuyen a esto
- Los talleres de diseño permiten que todo el mundo se entere de las decisiones que afectan al diseño al mismo tiempo, sin pérdidas de tiempo
- Principio ágil: la conversación es la forma más eficiente y eficaz de transmitir contenidos
- Facilitan el aprendizaje de aquellos con menos experiencia
- Facilitan llegar a consensos, la coordinación de equipos y el intercambio de ideas
Talleres de diseño ágil¶
- Las personas no hemos evolucionado para usar ratones y mirar fijamente pantallas de ordenador
- Nos es más natural, y más agradable, pintarrajear las paredes y poder movernos con libertad
- Las personas nos adaptamos bien a obtener información visualmente, por eso usamos notaciones gráficas como UML
- Pero no hace falta “pasarse” con el UML
- Buscamos tener una conversación con un lenguaje cuya sintaxis principal sea compartida, no tratar de formalizar una especificación
- Pero no hace falta “pasarse” con el UML
- La duración de un taller depende del número de participantes y de las tareas a realizar
- Pueden ser horas o días (no muchos), pero siempre timeboxed
Talleres de documentación de la arquitectura del sistema¶
Talleres de documentación de la arquitectura del sistema
Talleres de documentación de la arquitectura del sistema¶
- Tras un tiempo, y conforme las guías maestras de la arquitectura se vayan estableciendo, se puede llevar a cabo un taller de documentación de la arquitectura del sistema
- Para educar a nuevos desarrolladores y para facilitar que todo el mundo involucrado conozca el estado de la arquitectura del sistema
- La documentación arquitectural resultante es útil como apoyo a la interacción entre personas
- Y puede ser imprescindible en un esfuerzo de desarrollo distribuido
Diferencias con los talleres de diseño ágiles¶
- Los talleres de diseño se hacen antes que el diseño real (el código)
- Proporcionan conversación, aprendizaje, especulación, guías y borradores en la pared
- Los talleres de documentación de la arquitectura se hacen después de la implementación
- Describen el sistema como es en un momento determinado
- Son informativos, no creativos, y los participantes aprenden sobre la arquitectura real
- El formato no tiene que ser especialmente formal, y escribir en las paredes y guardar fotos sigue siendo útil
La deuda técnica ( technical debt )¶
La deuda técnica ( technical debt )
La deuda técnica¶
- Los atajos que tomamos deliberadamente para entregar antes algo que funcione se pueden ver como la adquisición de una deuda
- Es una deuda técnica
- Estos atajos son cosas relativamente mal hechas que habría que mejorar lo antes posible
- Porque cuanto más tardemos en pagar la deuda técnica, más intereses acumulará
- La deuda y los intereses los pagaremos en tiempo de desarrollo en el futuro
- Pagaremos toda la deuda refactorizando el código
- O seguiremos pagando intereses poniendo parche tras parche sin solucionar los problemas de raíz
- Esta es una deuda técnica estratégica
- Elegimos tomar algún atajo en el desarrollo de un producto para poder ser los primeros en comercializarlo, o para poder empezar a generar algún beneficio
La deuda técnica¶
- También se habla de deuda técnica para referirnos a problemas típicos en desarrollo de software
- Mal diseño, o diseño desactualizado, bugs, cobertura de tests insuficiente, demasiados tests manuales, mala integración y control de versiones, falta de experiencia en la tecnología que usamos etc.
- A este tipo de deuda técnica se la llama “deuda ingenua ”, “deuda no intencionada ”, “deuda imprudente ” o simplemente “ chapuza ”
- No es intencionada
- Puede ser por irresponsabilidad y/o accidente
- Se corrige principalmente con formación y decisiones empresariales acertadas
- P.ej., invertir en formación para el personal
- No es intencionada
La deuda técnica¶
- Finalmente también hay una deuda técnica inevitable
- Inevitable e imprevisible
- Por ejemplo, hay decisiones de diseño tempranas que tendremos que cambiar conforme aprendemos más del sistema que estamos creando
Consecuencias de la deuda técnica¶
- Punto crítico impredecible
- En algún momento, no predecible, se llega a un punto crítico
- Desde ahí, casi cualquier mínimo cambio puede crear grandes problemas
- Tiempo de entrega incrementado
- Cuanto mayor sea la deuda hoy, menor será la velocidad (características implementadas por sprint) mañana
- El tiempo que necesitamos para pagar los intereses o la propia deuda no lo usamos para implementar características útiles
- Cuanto mayor sea la deuda hoy, menor será la velocidad (características implementadas por sprint) mañana
- Aumenta el número de defectos
- La deuda afecta cada vez a más cosas de las que implementamos, con lo que aumenta el número de defectos
Consecuencias de la deuda técnica¶
- Aumenta el coste de desarrollo y de soporte
- Cualquier cambio pequeño es más costoso en presencia de deuda técnica
- Atrofia de producto
- Conforme más tardamos en añadir nuevas características o arreglar defectos en nuestro producto, este se vuelve menos atractivo para los clientes (actuales y potenciales)
- Menor previsibilidad
- Cualquier estimación relacionada con el desarrollo será menos fiable en presencia de deuda técnica
Consecuencias de la deuda técnica¶
- Expectativas del producto disminuidas, frustración y menor satisfacción por parte de los clientes
- Puesto que la deuda hace más costoso cualquier desarrollo, las expectativas sobre el producto disminuyen
- Los clientes ven que el producto no mejora, o incluso empeora, con el tiempo
- Como las expectativas de los clientes se ven reducidas, la empresa dedica menos entusiasmo a venderlo/usarlo
- También porque los de ventas ven un producto que cada vez funciona peor y que por tanto les cuesta más venderlo
- Puesto que la deuda hace más costoso cualquier desarrollo, las expectativas sobre el producto disminuyen
2014-01-04¶
2015-09-01¶
2020-09-17¶
2021-07-21¶
2022-11-16¶
2023-08-21¶
Causas de la deuda técnica¶
- Las causas son distintas según la deuda sea estratégica, ingenua o inevitable
- Presión por cumplir con una fecha límite
- Tanto la estratégica como la chapucera pueden deberse a esta presión
- En determinado momento se comprueba que a la velocidad actual no se podrá cumplir con la fecha límite
- En lugar de reducir el alcance o alargar el límite (que sería lo ideal), se impone que el equipo debe aumentar su velocidad
- Esto es la infame “calidad flexible”
- La consecuencia es deuda técnica
- Una de las primeras cosas que se suele hacer es reducir el tiempo de pruebas
- Esto aumenta la deuda y tarde o temprano disminuye la velocidad, consiguiendo a medio plazo lo contrario de lo que se pretendía
- La deuda técnica se acumula
- Acelerar el lanzamiento de la versión 1, incurriendo en deuda, va a retrasar el lanzamiento de la versión 2 que ahora tiene que arrastrar esta deuda acumulada
Gestionar la acumulación de la deuda técnica¶
- La deuda técnica es inevitable
- Tener un producto [casi] sin deuda es económicamente inviable
- La gestión de la deuda técnica es un tema técnico y del negocio
- Si se acumula mucha llegamos al punto crítico inmanejable
- El primer paso es evitar crear deuda chapucera
- Para ello nos centraremos en un buen diseño, desarrollo dirigido por tests, integración continua, tests automáticos, refactorización...
- Hay que tener una definición de “hecho” fuerte
Gestionar la acumulación de la deuda técnica¶
- Hay que entender las consecuencias económicas (el coste) de la deuda técnica
- Obvio: el coste de tener que arreglar, más tarde, lo que se hizo mal al principio
- No tan obvio: coste de oportunidad por estar pagando deuda en lugar de desarrollando nuevas características
- No tan obvio: como pagar la deuda no da beneficios inmediatos, muchas empresas lo retrasan
- Pero retrasarlo implica estar pagando intereses durante más tiempo
- Decidir sobre la viabilidad económica de adquirir deuda técnica no suele ser fácil
- La mayoría de empresas tienden a subestimar el coste de la deuda técnica
Hacer visible la deuda técnica¶
- Normalmente esta deuda es más visible para los desarrolladores que para la dirección de la empresa
- Aunque la dirección será perfectamente consciente de la deuda financiera de esa empresa
- Aunque no haya (todavía) una forma clara de estimar el coste de la deuda técnica, cada organización necesita encontrar una forma de comunicarla a la dirección en términos económicos
- A veces mostrar la velocidad de los equipos en el tiempo (que disminuye con la deuda) puede ayudar
- Con las debidas cautelas: la velocidad se suele medir en puntos de historia por sprint, pero los puntos de historia son una medida relativa
- Cualquier métrica que muestre que el tiempo de entrega de nuevas características es cada vez mayor también puede ser una buena opción
- A veces mostrar la velocidad de los equipos en el tiempo (que disminuye con la deuda) puede ayudar
Hacer visible la deuda técnica¶
- Aunque a nivel técnico se sepa que hay deuda técnica, sigue siendo necesario concretarla
- Se pueden añadir como entradas del sistema de seguimiento de cambios/errores
- “ Deuda: La clase A debería separarse en dos por modularidad”
- Se pueden añadir entradas de deuda a la pila del producto
- Pueden de esta forma priorizarse, estimarse y añadirse a sprints y son visibles para el dueño del producto
- O se puede tener una “pila o tablero de deuda” separada y tomarla como una entrada más al decidir las tareas de un sprint
- Se pueden añadir como entradas del sistema de seguimiento de cambios/errores
Pagar la deuda técnica¶
- Primero, hay deuda técnica que no debería pagarse
- La de un producto cerca del final de su vida
- La de un prototipo
- Los prototipos se tiran , no se deben usar como base para desarrollar cosas
- La de un producto desarrollado para tener una vida corta
- Cuando hay que pagarla, se puede aplicar la “regla del Boy Scout”
- Deja el sitio de acampada más limpio de lo que lo encontraste
- Cada vez que toques código, intenta dejarlo un poco mejor de lo que estaba
- Deja el sitio de acampada más limpio de lo que lo encontraste
- Esto tiene un coste añadido, y hay que cuantificarlo
- Se puede tomar un porcentaje de la capacidad del equipo en cada sprint que irá para el mantenimiento de la deuda
Pagar la deuda técnica¶
- Es mejor pagar la deuda poco a poco que de golpe
- Es como pagar la hipoteca mes a mes; poco a poco reduces el dinero que debes al banco
- Tener sprints exclusivos de pago de deuda puede ser útil (o necesario) en alguna ocasión
- Pero suele indicar que no se le ha prestado la debida atención a la deuda técnica y que ha crecido sin control
- Y no encaja nada bien con una base de Scrum, que es completar características valiosas potencialmente entregables en cada sprint
- Es mejor pagar antes la deuda que tiene intereses más altos
- Por ejemplo, la de un módulo que usan muchos otros, y que necesita desesperadamente una refactorización, antes que la de un módulo que no usa casi nadie
La deuda técnica en una gráfica¶
¶
-
Deuda técnica en Google
-
Deuda técnica en Google
Deuda técnica en Google¶
- Las siguientes transparencias están basadas en un artículo publicado en 2012, centrado específicamente en la deuda técnica relacionada con la construcción automática
- Las cifras habrán cambiado, pero las ideas generales son igual de relevantes
- El código de Google es enorme y se gestiona en general como un gran monolito
- Un único sistema de build (multilenguaje)
- Un único repositorio de código fuente
- Una única infraestructura de integración continua
- ...
Deuda técnica en Google¶
- Eso tiene ventajas
- Todo el mundo sigue las mismas reglas de estilo de codificación
- Las mejoras en automatización se aplican a todos los proyectos
- Se puede buscar en todo el código desde un único sitio
- Es fácil aprovecharse de otros proyectos
- Pero también desventajas
- Una API de bajo nivel puede acabar siendo usada, en poco tiempo, por cientos de proyectos
- Si hay que hacer un cambio que en un proyecto pequeño sería una rápida refactorización con el IDE (p.ej., renombrar una clase), a esta escala puede tardar días o incluso semanas
- No solo por lo grande que es el código, sino por lo rápido que cambia
- De media hay 12 commits por minuto
- No solo por lo grande que es el código, sino por lo rápido que cambia
Dependencias innecesarias o indirectas¶
- Hay proyectos que declaran dependencias innecesarias
- Exigen un trabajo adicional innecesario por parte de los sistemas de construcción y prueba
- Hay proyectos que no declaran directamente dependencias que sí necesitan
- El proyecto Pr1 depende de Pr2 y de Pr3, pero solo declara Pr1 → Pr2
- Sin embargo, como Pr2 → Pr3, Pr1 puede usar Pr3 sin problemas y todo funciona...
- ...hasta que Pr2 deja de necesitar a Pr3 y lo elimina de sus dependencias, momento en el que Pr1 deja de funcionar
Dependencias innecesarias o indirectas¶
- Estos problemas se podrían abordar manualmente haciendo, p.ej., que un día estuviera dedicado exclusivamente a que cada proyecto revisara sus dependencias
- Esta solución tendría varios problemas
- Como es manual, si el cambio es complicado o da muchos problemas, lo más fácil es dejarlo como estaba
- No evita que este problema vuelva a empezar a acumularse inmediatamente después de este día
Dependencias innecesarias o indirectas¶
- Una mejor solución es automatizar, al menos en parte, la solución
- Aprovechar adecuadamente el compilador para distinguir dependencias directas e indirectas en y generar un warning o un error por cada dependencia indirecta
- A partir de eso, se puede hacer que el sistema de construcción
- Y una vez eliminado este problema, y solo entonces , se puede hacer que las dependencias que no se usan se eliminen automáticamente
- Si tratamos de eliminar las dependencias que no se usan antes de solucionar este problema:
- Si Pr1 declara Pr1 → Pr2, y Pr2 declara Pr2 → Pr3, pero en realidad
- Pr1 depende de cosas de Pr3 aunque no lo declare
- Pr1 no depende de cosas de Pr2 aunque sí lo declara
- Parece que la dependencia Pr1 → Pr2 no se usa, pero si la elimináramos automáticamente, Pr1 dejaría de funcionar
- Si Pr1 declara Pr1 → Pr2, y Pr2 declara Pr2 → Pr3, pero en realidad
- Si tratamos de eliminar las dependencias que no se usan antes de solucionar este problema:
Dependencias infrautilizadas¶
- Otro problema ocurre cuando hay bibliotecas que se usan en muchos proyectos, pero la mayor parte de estos usan solo una pequeña parte de las mismas
- El tiempo de construcción de estos proyectos es el mismo que si necesitaran la biblioteca completa
- La solución es modularizar mejor el código de esas bibliotecas
- Esto no es muy automatizable
- La solución en este caso pasa por crear herramientas que permitan a los desarrolladores visualizar y entender mejor las dependencias de su código para tomar mejores decisiones sobre modularización
Proyectos zombie¶
- Proyectos que ya no se mantienen, pero que todavía se usan en otros proyectos
- Los equipos que trabajan en los proyectos que usan estos zombies tienen que dedicar tiempo a entender y arreglar problemas y bugs en proyectos que deberían estar muertos y enterrados
- Cuando un proyecto no se compila, puede ser un problema transitorio o puede ser que sea un zombie
- En Google decidieron que si algo no se compilaba correctamente durante al menos 90 días se declaraba oficialmente muerto
- Después de esos 90 días, los proyectos pueden ser eliminados, con lo que se evita que se vuelvan zombies
Acoplamiento excesivo¶
- Cuando un proyecto depende de detalles de la implementación de otro en lugar de en sus interfaces públicas y documentadas se crea la peor clase de acoplamiento
- El otro proyecto no puede ser modificado libremente, porque cualquier cambio interno, aunque no altere su interfaz, podría romper al primero
Acoplamiento excesivo¶
- En un sistema como el de Google, donde por defecto todo el código de todos los proyectos es visible y fácilmente usable por todos los demás, este problema aparece muy a menudo
- La medida que se decidió aplicar fue hacer que por defecto los nuevos proyectos que se crearan fueran privados
- Esto buscaba enfatizar que ciertos proyectos no están pensados para ser reusables
- Evitando así que se reuse un código que no tiene unas interfaces públicas adecuadas y bien documentadas
- La medida no evita el problema, pero lo reduce
- La medida encontró cierta resistencia interna en Google, pues parecía contraria a la filosofía de desarrollo de la empresa que algo fuera privado por defecto, pero el resultado fue positivo y no creó problemas
- La lección aprendida aquí es que ciertas decisiones, si están respaldadas por análisis de coste-beneficio racionales y globales, deben poder ser tomadas incluso aunque no sean populares
Bibliografía¶
- Craig Larman & Bas Vodde. Practices for Scaling Lean & Agile Development. Large, Multisite and Offshore Product Development with Large-Scale Scrum
- Capítulo 8 ( Design & Architecture )
- Kenneth S. Rubin. Essential Scrum. A practical guide to the most popular agile process
- Capítulo 8 ( Technical Debt )
- J. David Morgenthaler, Misha Gridnev, Raluca Sauciuc, Sanjay Bhansali. Searching for Build Debt: Experiences Managing Technical Debt at Google. Proceedings of the Third International Workshop on Managing Technical Debt, IEEE (2012).