- La participación real en el diseño de sistemas a gran escala solo es posible para los ingenieros que trabajan directamente con ese código, y los consejos abstractos casi siempre carecen de valor
- El consejo general de diseño (generic design) suele darse entendiendo el dominio, pero sin conocer la base de código
- En el trabajo real, las restricciones concretas y mantener la consistencia son mucho más importantes que los principios de diseño, y entender el estado actual del código es clave
- Al diseñar un sistema nuevo o decidir la dirección tecnológica de toda la empresa, los principios generales de diseño sí pueden ser parcialmente útiles
- Sin embargo, las estructuras de diseño centradas en arquitectos separados de la realidad del trabajo suelen fracasar, y quien propone el diseño debe responsabilizarse por el resultado
Límites del diseño de software general
- Para diseñar sistemas a gran escala, es indispensable un entendimiento profundo de los detalles concretos del código
- Los consejos abstractos casi no ayudan a resolver problemas reales
- En la práctica, la consistencia (consistency) es más importante que un “buen diseño”
- Como las bases de código reales son complejas y producen resultados impredecibles, las formas de implementación que pueden elegirse para hacer cambios seguros son limitadas
- Una gran base de código compartida siempre está en un estado intermedio donde conviven varios diseños, y el estado actual de acoplamiento del código importa más que una meta ideal
- Como en la mayoría de los sistemas es imposible una reescritura completa (rewrite), hay que apoyarse en la consistencia interna y en el cuidado minucioso de los ingenieros
Características del diseño de software concreto
- Las discusiones de diseño efectivas ocurren en conversaciones entre unos pocos ingenieros que trabajan con el sistema todos los días
- Los temas de discusión no son principios generales, sino contextos concretos como la estructura detallada del sistema o el flujo de datos
- Por ejemplo, en lugar de discutir si “DRY es bueno”, se dan discusiones técnicas detalladas como “¿se puede poner esta función en el subsistema A?” o “¿la información B está accesible en el contexto C?”
- Las contribuciones importantes surgen al corregir pequeños malentendidos o el impacto detallado de cambios en el código
Cuándo sí es útil el consejo general de diseño
- Al diseñar un proyecto nuevo desde cero, los principios generales son útiles porque aún no existen restricciones concretas
- Cuando cuesta elegir entre varias implementaciones, los principios generales pueden servir como criterio de desempate (tie-breaker)
- También ayudan a mantener la consistencia a nivel de toda la empresa, y esa es una de las funciones formales del arquitecto de software
- Incluso en decisiones tecnológicas amplias como cloud vs on-premise, AWS vs Azure, los principios generales pueden servir de referencia, aunque todavía no se pueden ignorar las restricciones concretas
Los arquitectos y el problema del “mínimo local”
- Muchas empresas caen en estructuras de diseño abstracto centradas en arquitectos sin experiencia de campo
- Este enfoque parece eficiente a simple vista, pero en la práctica produce diseños que los ingenieros de campo no pueden implementar
- Como los arquitectos no implementan directamente, les falta responsabilidad sobre el resultado (skin in the game)
- Si el diseño tiene éxito, se llevan el mérito; si falla, pueden culpar al equipo de ejecución
- Este tipo de estructura tiende a reforzar actividades formales de diseño más que el valor real
Conclusión y propuesta
- Las discusiones de diseño útiles ocurren en conversaciones concretas al nivel del código, y quien diseña debe conocer bien la base de código
- Los principios generales de arquitectura deben limitarse al diseño de sistemas nuevos, al apoyo en decisiones puntuales de sistemas existentes y a definir la dirección tecnológica a nivel de empresa
- Quien propone el diseño de un proyecto debe asumir responsabilidad por su éxito o fracaso, y los ingenieros que realmente trabajan con el código deben ser los protagonistas del diseño
- Así, quien entiende y puede desplegar el sistema real podrá ser reconocido como el verdadero diseñador
4 comentarios
> En el trabajo real, las restricciones concretas y mantener la consistencia son mucho más importantes que los principios de diseño, y entender el estado actual del código es clave.
Es una idea que siempre he defendido, así que me da gusto al corazón.
Con razón últimamente los gurús dicen que los recién llegados hasta usan mucho mejor los agentes. Como era algo que les daba dinero por mucho tiempo, no hacen el
unlearning.¿No sería posible resolver suficientemente bien los puntos planteados si se mejorara el proceso de completar la arquitectura?
Opiniones de Hacker News
Describe la situación en la que, en una reunión de equipo, en vez de hablar de cosas como “¿DRY es mejor o WET?”, la conversación deriva en debates complejos de dependencias como “¿podemos meter esta funcionalidad en el subsistema A? No, ahí no tenemos la información de B, y para exponerla habría que reescribir D...”
Dice en tono de broma que es una escena muy familiar, enumera varios nombres de sistemas ficticios y al final agrega un enlace de YouTube
Llevo 30 años desarrollando, pero casi nunca he visto casos en los que realmente se invierta un esfuerzo consistente en diseño y arquitectura
La mayoría de los “arquitectos” no diseñan nada; la estructura suele ser que un desarrollador senior diseña y luego solo recibe retroalimentación
Si la permanencia promedio es de 2 años, la gente termina diseñando entendiendo apenas una parte del sistema, y muchas veces el arquitecto solo da el visto bueno
‘Generic Software Design’ sirve para orientar la dirección de implementación. Proporciona un lenguaje y un marco comunes que facilitan resolver problemas
Pero la implementación real puede terminar siendo distinta al plan. Como en la teoría de la programación de Naur, el conocimiento real del sistema está en la cabeza de los desarrolladores
La frase “en una base de código grande, la consistencia importa más que un buen diseño” es justamente una trampa de ese tipo de consejo generalizado
Si solo se enfatiza la consistencia, los malos hábitos se quedan intactos
De un lado están los “arquitectos” que no entienden la realidad, y del otro los Real Programmer obsesionados solo con optimizar detalles
Ambos extremos son problemáticos, y quien toma decisiones debe entender tanto los detalles como el contexto
Como historia relacionada, mencionan The Story of Mel
Estoy de acuerdo con la idea de que “la persona que hizo el diseño debe hacerse responsable del éxito y el fracaso del proyecto”
Eso también debería aplicarse a quien eligió la metodología de desarrollo. Un Scrum master no carga el mismo nivel de responsabilidad que un lead engineer
Las mejores apps en las que he participado tenían estas tres características
Esa libertad elevaba tanto la satisfacción de los desarrolladores como la calidad del producto
En mi experiencia, en una base de código grande la obsesión con la consistencia en realidad es un error
Cada módulo tiene requisitos distintos, así que también deberían variar la estrategia de testing o los nombres
En el caso ideal, el desarrollador también debería ser usuario real del software que crea
Así puede sentir directamente los errores o incomodidades y tener motivación para mejorarlos
Un arquitecto de software separado que no participa en el mantenimiento no es algo realista
Los proyectos cambian constantemente, así que un rol que solo da instrucciones desde lejos no ayuda