ARCHITECTURE.md (2021): especificación técnica de la estructura del proyecto
(matklad.github.io)- En proyectos open source de entre 10k y 200k líneas, tener un documento ARCHITECTURE junto a
READMEyCONTRIBUTINGpuede reducir el costo para que nuevos contribuidores entiendan la estructura del código - En un proyecto desconocido, el problema mayor no es que escribir un parche sea aproximadamente 2 veces más lento, sino que encontrar dónde hay que modificar puede tomar 10 veces más
- Este documento debe incluir de forma breve la estructura de alto nivel y contenidos que no cambian con frecuencia; en lugar de mantenerlo sincronizado continuamente con el código, conviene revisarlo varias veces al año
- Sus componentes centrales son una vista general del problema y un mapa de código (codemap); debe mostrar los módulos grandes y sus relaciones para responder “dónde está el código encargado de X”
- Conviene dejar registrados nombres importantes, invariantes arquitectónicas, límites entre capas y sistemas, y preocupaciones transversales; fomentar la búsqueda por nombre en vez de enlaces directos reduce la carga de mantenimiento
El costo que reduce un documento ARCHITECTURE
- En un proyecto open source, la mayor diferencia entre alguien que contribuye ocasionalmente y un desarrollador core es si conoce la arquitectura física del proyecto
- En una base de código desconocida, uno termina leyendo los archivos secuencialmente, como fragmentos lógicos puestos en un orden arbitrario
- Un desarrollador que ya hizo contribuciones significativas tiene en la cabeza un mapa del código que le permite ir directo al lugar necesario; si ese lugar no existe, incluso puede mover ese código
- Un archivo
ARCHITECTUREes una forma de reducir esa brecha a bajo costo - El documento debe ser breve
- Porque todas las personas que contribuyen de forma recurrente deberían leerlo
- Cuanto más breve sea, menor será la probabilidad de que cambios futuros lo invaliden
- El criterio para
ARCHITECTUREes incluir contenido que no cambie con frecuencia- No se intenta mantenerlo continuamente sincronizado con el código
- En cambio, se vuelve a revisar varias veces al año
Qué debería incluir
- Primero, resumir el problema que resuelve el proyecto a nivel de vista general
- Luego, escribir un mapa de código (codemap) con cierto nivel de detalle
- Explica los módulos de gran escala y sus relaciones entre sí
- Debe responder “dónde está lo que hace X”
- También debe responder “qué hace esto que estoy viendo”
- No profundiza en el funcionamiento interno de cada módulo
- Ese contenido va en documentación separada o, mejor aún, en documentación inline
- El mapa de código es un mapa del país, no un atlas por estados
- Al escribir el mapa de código, también se puede revisar la estructura del proyecto
- Se puede comprobar si las cosas que se quieren mantener cerca en el mapa de código también aparecen adyacentes en el resultado de ejecutar
tree .
- Se puede comprobar si las cosas que se quieren mantener cerca en el mapa de código también aparecen adyacentes en el resultado de ejecutar
- Se deben nombrar explícitamente archivos, módulos y tipos importantes
- Conviene evitar enlaces directos, porque pueden romperse con el tiempo
- En su lugar, fomentar la búsqueda de símbolos por nombre permite descubrir también elementos relacionados con nombres similares, sin carga de mantenimiento
- Las invariantes arquitectónicas deben escribirse explícitamente
- Las invariantes importantes muchas veces aparecen en forma de algo que “no existe”
- Por ejemplo, en desarrollo web, el hecho de que la capa de modelo no dependa de la vista puede ser difícil de deducir leyendo solo el código
- También se deben marcar los límites entre capas y sistemas
- Un límite sugiere información sobre la implementación del sistema que está detrás
- Restringe todas las implementaciones posibles
- Como un buen límite es difícil de encontrar al azar en el código, documentarlo es útil
- Después del mapa de código, se agrega una sección separada para preocupaciones transversales
- Un ejemplo útil se puede ver en architecture.md de rust-analyzer
1 comentarios
Opiniones de Hacker News
Me gusta esta idea y creo que, sin importar el tamaño del repositorio, una descripción de la arquitectura también tiene lugar en el README.
Por ejemplo, como me parece importante que todos los lectores vean y entiendan el flujo de trabajo, puse deliberadamente un diagrama de secuencia Mermaid[1] en el README principal[2].
[1] https://mermaid.js.org/syntax/sequenceDiagram.html
[2] https://github.com/hbcondo/revenut-app?tab=readme-ov-file#-w...
Suena como un muy buen consejo.
Ojalá mejoraran las herramientas para visualizar la arquitectura de un sistema en ejecución. Es raro que leer código o ver archivos Markdown siga siendo el enfoque moderno. Con suerte, quizá haya algún diagrama Mermaid.
Me gustaría que la arquitectura se revelara por sí sola en tiempo real. Sería ideal que la observabilidad a escala macro viniera integrada por defecto, y creo que también ayudaría a todos a entender mejor la computación y a que la humanidad se aumente a sí misma.
Para proyectos open source con muchos colaboradores temporales, parece un modelo de bajo mantenimiento bastante bueno. Si el proyecto tiene ingenieros dedicados, también vale la pena considerar ADR.
Los ADR requieren más mantenimiento, pero dejan registrado “por qué se hizo así” y “qué alternativas se evaluaron”, por lo que son muy útiles al rediseñar.
Referencia: https://adr.github.io/
ARCHITECTURE.md contiene el estado actual de la arquitectura, y ADR es el registro de las decisiones que llevaron hasta ahí. Ambos son muy útiles.
Microservicios, Kafka, Kubernetes: porque ahora tenemos 4 mil usuarios, pero ¿qué pasa si algún día llegamos a mil millones?
GraphDB: porque ¿qué pasa si SQL no alcanza?
ElasticSearch: porque ¿qué pasa si además de estadísticas también necesitamos búsqueda de texto completo?
Pero la mayoría de esos documentos terminan siendo una forma abreviada de “quiero probar una nueva arquitectura/tecnología porque es divertida, la usa un colega que trabaja en FAANG, leí ese libro, se ve bien en el CV”.
Cuando ellos pasan al diseño del siguiente gran proyecto, nuestro equipo tiene que mantener sincronizados más servicios que integrantes del equipo, junto con esas bases de datos y tecnologías. Claro, se trata como si esos problemas fueran mucho más simples que tomar “grandes decisiones de arquitectura”.
Se me acaba de ocurrir que todos los IDE que he usado muestran a la izquierda la estructura de carpetas del proyecto como un árbol de directorios estándar. ¿Hay algún IDE que permita explorar el proyecto como un grafo de dependencias?
Creo que una representación tipo índice no encaja bien. En mi flujo de trabajo de programación actual, abro una terminal, ejecuto ranger dentro de ella y cambio a esa terminal cuando quiero explorar la estructura de directorios a izquierda y derecha. Abro VSCode y, en una terminal dividida, uso la parte superior como terminal normal y la inferior para ejecutar Ranger. También sirve Midnight Commander; en realidad, cualquier explorador de archivos TUI alcanza.
Además, empecé a poner un mapa de código en el archivo architecture.md del proyecto. Si ejecutas
tree -L, puedes obtener un diagrama de árbol de la estructura de archivos, con la profundidad que quieras, listo para pegar en Markdown. Agrego esa salida al Markdown y, después de cada archivo/carpeta, pongo un comentario de menos de 10 palabras explicando su propósito.Ranger - https://github.com/ranger/ranger
Midnight Commander - https://midnight-commander.org/
Tengo dos ideas de cómo podría verse.
Primero, varios árboles de directorios que organicen los archivos de forma ortogonal usando enlaces simbólicos. La estructura de directorios habitual se divide en cliente/servidor, pero ¿qué pasaría si quisiera dividirla por funcionalidad? Un IDE podría facilitar mucho eso.
Segundo, en la línea de este artículo, me gustaría que el IDE permitiera crear marcadores y moverse entre ellos para explicar el código más fácilmente a otras personas. A veces quiero dejar un comentario y, al hacer clic, saltar a otro lugar del codebase. Si se conectan estas cosas, se puede construir una narración que explique cómo funciona todo el codebase.
Me pregunto si hay gente trabajando en algo así.
Creo que hay que tener cuidado con extender demasiado lo que dice el autor aquí a proyectos de software en general.
En proyectos open source grandes con muchos colaboradores que carecen de contexto, vale mucho la pena mantener este tipo de documento. Pero en proyectos laborales pequeños, he visto que todos los documentos que los desarrolladores commitean terminan sin mantenimiento.
Como mínimo, descubrimos que los integrantes del equipo tenían ideas muy distintas entre sí sobre la arquitectura actual y la arquitectura ideal. Solo hacer eso explícito ya justifica crear el documento.
Y “la documentación no se mantiene” es una razón muy débil para no crear documentación. Cualquier documentación, incluso una desactualizada o sutilmente incorrecta, es mejor que “no tener documentación”.
Hace unos años experimenté con un enfoque similar en uno de mis proyectos paralelos grandes
https://github.com/shipmight/shipmight/blob/master/src/ARCHI...
En la parte superior de cada archivo dejé un árbol de enlaces a otros archivos ARCHITECTURE.md dentro del repositorio. Un ejemplo sería: ARCHITECTURE.md <- ubicación actual, backend/ARCHITECTURE.md, backend/api/ARCHITECTURE.md, backend/cli/ARCHITECTURE.md, backend/ui/ARCHITECTURE.md, backend/utils/ARCHITECTURE.md, frontend/ARCHITECTURE.md, internal-charts/ARCHITECTURE.md
Se ve en lugares como este: https://github.com/shipmight/shipmight/tree/master/src/backe...
También he visto este enfoque en algunos proyectos
Cuanto más corto, menos probable es que cambios futuros lo invaliden. La regla práctica clave de ARCHITECTURE es escribir solo contenido que no cambie con frecuencia. No hay que intentar sincronizarlo con el código
Es menos probable que las interfaces cambien, y además son más difíciles de cambiar. Es la perspectiva de Parnas sobre los criterios usados para descomponer un sistema en módulos
Coincido en que es difícil entender una base de código. Ponerles nombre a los “patrones” ayuda hasta cierto punto, pero al final hay que leer bastante
En GitHub, los mensajes de commit por archivo muchas veces se sienten como explicaciones. ¿Será que podrían ser más útiles?
En todos los proyectos en los que participé, durante el onboarding recibí diagramas de arquitectura y una breve explicación de los componentes
Por eso me sorprende que esto no sea tan común en open source
En los proyectos open source no existe el primer día de trabajo de un empleado, así que tampoco existe esa introducción
Si no tienes muchísimo tiempo, estas explicaciones no son muy buenas. Se espera que un empleado tarde semanas en poder hacer algo por su cuenta, pero nosotros, como consultores de seguridad, recibimos una explicación completamente nueva cada 2 semanas. El problema es que esas explicaciones son improvisadas, no están estructuradas y, por la maldición del conocimiento, la persona que habla menciona muchos detalles irrelevantes
Probablemente lo mejor sería que alguien nuevo en el repositorio escriba esto una vez y que después solo se mantenga. La segunda mejor opción es que, en vez de que cualquiera lo explique improvisadamente cada vez, se tome un minuto para pensar qué incluir y qué omitir, y lo deje por escrito. Como dijo el autor, este archivo debe explicar la arquitectura de alto nivel del proyecto y debe ser breve. Todos los contribuidores recurrentes deberían leerlo, y cuanto más corto sea, menos probable será que futuros cambios lo invaliden
Siempre me pareció una práctica muy útil. Muchos proyectos tienen unos pocos archivos clave, o paquetes/módulos, etc., donde ocurre la mayor parte de los cambios
Si los nuevos contribuidores, o los que vuelven después de mucho tiempo, pueden familiarizarse rápido con ellos, el tiempo para arrancar en el proyecto se reduce mucho
En varios trabajos agregué archivos de arquitectura a proyectos [0], [1] y la reacción fue buena. No es perfecto, pero es mejor que no tener nada
[0]: https://github.com/zapier/zapier-platform/pull/324
[1]: https://github.com/stripe/stripe-cli/blob/master/ARCHITECTUR...
Antes me gustaban estos pequeños estándares de documentación/diagramas-as-code
Desarrollo guiado por README, ARCHITECTURE.md, ADR, arc42, C4, etc.
Ahora simplemente pongo un vault de Obsidian dentro de la carpeta
/docsdel repositorio gitEn vez de usar estándares ajenos, sigo organizando y refactorizando la documentación como administro mis notas personales en Obsidian
Al principio quería usar un subconjunto común de Markdown que funcionara tanto con GFM de GitHub como con Obsidian, pero me rendí, y ahora uso Markdown al estilo Obsidian tal cual, incluyendo funciones propias como el plugin Dataview y plantillas
Mermaid y LaTeX vienen integrados en Obsidian, y también hay un plugin de PlantUML. Para dibujos/diagramas visuales uso Canvas integrado, DrawIO y Excalidraw