La tragedia del código compartido y el síndrome de las ventanas rotas
Cuando acciones que pueden parecer racionales de manera aislada, producen un efecto acumulativo que puede ser perjudicial para el proyecto en su totalidad.
Parte de este artículo fue publicado originalmente en Marzo de 2024 en mi blog. De vez en cuando rescataré en esta newsletter los artículos que he escrito a lo largo de los años y que han generado mayor interés.
“En el caso de un recurso compartido, todos los usuarios se benefician directamente de su explotación, pero comparten los costes del abuso de ese recurso. Por tanto, el vínculo de retroalimentación entre el estado del recurso y las decisiones de los usuarios es muy débil. La consecuencia es la sobreexplotación del recurso, que se erosiona hasta que nadie puede disponer de él.”
― Donella Meadows. Pensar en sistemas
La tragedia de los recursos comunes es un concepto económico que ilustra cómo individuos actuando de manera independiente y racional según sus propios intereses pueden actuar en contra del bien común, agotando o degradando un recurso compartido a través de su acción colectiva. Este concepto que fue popularizado por Garrett Hardin en 1968, encuentra un claro ejemplo en la sobrepesca, donde cada pescador está motivado a capturar más peces, lo que eventualmente lleva a la disminución de la población de peces y al deterioro de la sustentabilidad de la pesca.
La tragedia ocurre porque cada individuo percibe que el beneficio de consumir un recurso adicional supera el costo que dicha acción impone sobre el bien común, resultando en el agotamiento del recurso para todos. Es crucial notar que las personas que consumen el recurso están incentivadas a incrementar su uso, contribuyendo a su eventual declive.
Si algo abunda en el desarrollo de producto son los recursos compartidos:
equipos de servicio
colas de trabajo
managers
plataformas
servicios
hardware
bases de datos
entornos: staging, desarrollo, etc.
pipelines
documentación
y fundamentalmente, el código.
El código como recurso compartido
Dentro del equipo
Cuando cada desarrolladora se centra solo en sus propias metas o tareas, introduciendo soluciones rápidas o escribiendo código de baja calidad sin considerar su impacto a largo plazo en la salud del proyecto, se genera una base de código cada vez más compleja de mantener y mejorar. Aunque cada acción pueda parecer racional de manera aislada, el efecto acumulativo puede ser perjudicial para el proyecto en su totalidad.
La teoría de las ventanas rotas
La teoría de las ventanas rotas, originaria de la criminología, sugiere que la presencia de desorden o la tolerancia hacia la degradación incentiva a más personas a contribuir al desorden. Aplicado al desarrollo de software, si la base de código contiene malas prácticas, desorden o soluciones precarias, es probable que otras desarrolladoras se sientan justificadas para seguir produciendo código de calidad similar. Esto puede llevar a una reducción en la calidad general del código y a mayores dificultades para su mantenimiento o mejora.
¿Egoísmo driven development?
Puede parecer que estos comportamientos surgen del egoísmo, pero cuanto más estudio los sistemas complejos más empatizo con la personas, pues rara vez actúan por mala intención. A menudo, son los incentivos perversos dentro de los sistemas los que llevan a las participantes en una tragedia de los comunes a ser indiferentes a su impacto en el colectivo, principalmente porque este efecto es invisible hasta que es demasiado tarde.
La suboptimización individual, donde las desarrolladoras son evaluadas por su rendimiento individual en lugar del rendimiento del equipo, producto u organización, es un problema subyacente.
Para contrarrestar esto, es fundamental promover una cultura de responsabilidad compartida por la calidad del código, donde las desarrolladoras se enfoquen no sólo en sus tareas inmediatas sino también en el bienestar a largo plazo del proyecto. Esto puede implicar prácticas como la revisión de código por pares, programación en parejas, establecimiento de estándares de calidad, refactorización regular, y un compromiso con prácticas de desarrollo sostenible. Requiere que reemplacemos en nuestro vocabulario el término “individual contributor”, que se ha estandarizado en las escaleras profesionales (Career Ladders), por “team contributor”.
Código compartido entre equipos
La propiedad clara en una base de código compartida es desafiante, especialmente si incluye código interrelacionado de varias áreas, dominios o productos con responsabilidades distribuidas entre diferentes equipos. Esto a menudo lleva a una propiedad compartida sin reglas claras, lo que puede generar conflictos y bloqueos.
Ante la falta de propiedad y el desafío de cambiar el statu quo, los incentivos para buscar soluciones rápidas son altos. Si ya existe una deuda técnica, caemos nuevamente en el síndrome de las ventanas rotas, aumentando exponencialmente los problemas.
Enfrentar el desafío de la propiedad compartida y la deuda técnica en una base de código manejada por múltiples equipos requiere un enfoque estratégico y colaborativo. Por ejemplo:
Desacoplamiento: Trabajar en desacoplar el código tanto como sea posible, dividiéndolo en módulos o componentes con interfaces bien definidas. Esto facilita la propiedad clara de cada pieza por parte de diferentes equipos.
Bounded Contexts: Aplicar el concepto de “Bounded Contexts” de Domain-Driven Design (DDD) para definir límites claros alrededor de diferentes dominios o áreas de responsabilidad, asegurando que las interacciones entre estos contextos sean explícitas y bien diseñadas.
Guías y estándares: Establecer guías de codificación y estándares de diseño que todos los equipos deben seguir, fomentando un nivel de calidad uniforme en toda la base de código.
Revisión de Código Cruzada: Practicar revisiones de código cruzadas entre equipos, lo que no solo mejora la calidad del código, sino que también fomenta el conocimiento compartido y reduce el riesgo de silos de conocimiento.
Soluciones a la trampa
En conclusión, he intentado trazar un paralelismo entre la tragedia de los comunes en el contexto económico tradicional y su manifestación en el desarrollo de software, resaltando cómo las acciones individuales, cuando no están alineadas con el bien común, pueden llevar a la degradación de recursos compartidos y tener un impacto negativo en la calidad del código.
Donella Meadows destaca tres estrategias fundamentales para superar la trampa de la tragedia de los comunes que a continuación intento adaptar a los problemas que he descrito en el post:
Educación y Concienciación
Educar y exhortar a las usuarias para que vean las consecuencias de la sobreexplotación del recurso. La formación continua y la sensibilización sobre las mejores prácticas de desarrollo, el impacto ambiental de las decisiones tecnológicas y la importancia de la sostenibilidad en el desarrollo pueden cultivar una cultura de responsabilidad y excelencia.
Reforzando el Vínculo de Retroalimentación
Implementar sistemas de revisión de código, pruebas automatizadas, y métricas de calidad que proporcionen una retroalimentación constante y oportuna sobre el impacto de las prácticas.
Privatización y Regulación del Acceso
Aunque la privatización de recursos en el desarrollo de software no siempre es aplicable, establecer claros límites de propiedad y responsabilidad sobre partes del código (por ejemplo, a través de microservicios, bounded contexts o componentes bien definidos) puede ayudar a que los equipos experimenten directamente las consecuencias de sus acciones, incentivándolos a mantener y mejorar la calidad del código.
Serie: las trampas de los sistemas complejos
Esta entrega forma parte de una serie sobre las trampas de los sistemas complejos aplicadas al desarrollo de productos:
Elusión de las reglas y persecución del objetivo equivocado: La trampa del testing coverage.
Desplazamiento de la carga hacia la intervención: La trampa de la adicción al parche.
Deriva hacia el bajo rendimiento: La Trampa de la Erosión de Metas y el Síndrome de la Rana Hervida.
Exclusión competitiva: La trampa del «rockstar developer».
Resistencia a las políticas: La trampa de los atajos y el falso dilema entre calidad y velocidad.
Tragedia de los recursos comunes: La tragedia del código compartido. (este artículo)
Si te interesa el tema del pensamiento sistémico aplicado al desarrollo de producto, de vez en cuando organizo talleres sobre cómo usar y sacarle partido a estas herramientas. Si estás interesado en que lo imparta para tu equipo o en algún evento, escríbeme.