Por qué deberías escribir ADR
(github.blog)ADR = Architecture Decision Records
Registrar dentro de la base de código por qué se tomaron ciertas decisiones de arquitectura.
GitHub lo está aplicando en sus equipos móviles de iOS/Android, y este es un artículo que explica por qué es necesario.
No es para ti, es para tu yo del futuro
Un ADR no es un proceso de reflexión sobre una decisión que tomaste, sino una ayuda para recordar el mindset que tenías cuando definiste esta arquitectura dentro de 6 a 12 meses.
Un ADR captura el momento en que se toma una decisión e incluye hasta los PoC tratados en reuniones, llamadas por Zoom, Slack y el código.
La idea es sacar de tu cabeza ese contexto y ponerlo en palabras para poder volver a meter ese mismo contexto en tu cabeza cuando revises esta arquitectura más adelante.
El verdadero bonus aparece cuando, meses después, alguien te reclama por qué el módulo GitHubAPIClient funciona de esta manera.
En lugar de pasar 30 minutos haciendo pairing para explicar el código, puedes pasarle este ADR y explicarle las decisiones que tomaste mientras construías ese módulo.
No es para ti, es para tus colegas
Un ADR debe contener algo más largo que una línea como: "esta funcionalidad es la implementación del feature-#3128".
Es una forma de explicación más extensa que ayuda a tus colegas a entender por qué esta funcionalidad se construyó de esta manera y no de otra.
(Expresado dentro del ADR como "alternativas consideradas", "ventajas y desventajas", etc.)
Lo que para ti es simple puede ser complejo para tus colegas.
Si te tomas un poco de tiempo para dejar por escrito el proceso de pensamiento que tuviste al tomar una decisión, les das a los miembros del equipo la oportunidad de entrar en tu cabeza.
Escribir ADR hace posible la "socialización de decisiones".
Así, en vez de que cada persona tome decisiones por separado, el equipo toma decisiones de las que también asume la responsabilidad de mantenimiento.
Si escribes un ADR antes de abrir un pull request, puedes recibir mejores revisiones de PR por parte del equipo que lo evalúa.
No es para ti, es para tus colegas del futuro
Un ADR no existe para mostrar qué tan inteligente eres ni para dejar a la gente confundida mirando la arquitectura que creaste.
Un ADR ayuda a que, cuando se incorpore un nuevo integrante al equipo, pueda entender la base de código actual y cómo esa base de código ha evolucionado con el tiempo.
A medida que el equipo se expande y crece, aumentan los caminos de comunicación entre sus integrantes.
Dejar registradas estas decisiones también ayuda a comunicarse con las personas que se suman cuando el equipo crece.
El mejor escenario es que un miembro de tu equipo escriba un ADR nuevo para reemplazar una decisión que tomaste en el pasado, y que en el futuro tú puedas aprender de tus colegas.
"Escriban más ADR. Cada vez que nuestro equipo crece y la base de código se vuelve más compleja, los ADR son una gran forma de ayudar a nuestro yo del futuro, a los miembros actuales del equipo y a los miembros futuros del equipo."
3 comentarios
Entre los casos famosos de gobierno electrónico, Gov.UK incluso tiene un repositorio donde organizan los ADR relacionados con su arquitectura de nube en AWS.
https://github.com/alphagov/govuk-aws/…
Me sirvió mucho como referencia.
Casos de ADR
Decisión de framework CSS
https://github.com/joelparkerhenderson/architecture_decision_record/…
Supuesto: queremos crear una web app moderna, rápida y responsiva, así que no queremos usar jQuery
Restricción: un framework que no requiera usar jQuery
Consideraciones: no usar nada, o elegir entre Bootstrap/Bulma/Foundation/Materialize/Semantic UI; se evaluó a fondo Bulma y Semantic UI
Monorepo vs Multirepo
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ usamos git como SCM, así que hay que decidir entre monorepo vs polyrepo vs híbrido
→ cuando la organización/equipo/proyecto es pequeño y la iteración es rápida, Monorepo
→ cuando la organización/equipo/proyecto es grande y lo importante es la estabilidad, Polyrepo
Decisión de lenguaje de programación
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ el frontend será TypeScript
→ el backend será Rust
→ el frontend debe ser común, pero permitir desarrollo, despliegue e iteración rápidos. No se necesita compatibilidad con legacy
→ el backend requiere un nivel algo más alto que lo común. Consideraciones de calidad, estabilidad y seguridad. Se necesita un nivel casi de tiempo real (no debe detenerse por GC). También son importantes la programación funcional, el procesamiento paralelo y multicore, y la seguridad de memoria
Restricción: debe poder ejecutarse obligatoriamente en el serverless de servicios cloud principales (Amazon Lamba)
Consideraciones: C/C++/Clojure/Elixir/Erlang/Elm/Flow/Go/Haskell/Java/Javascript/Kotlin/Python/Ruby/Rust/TypeScript
Debate:
→ C: descartado por baja seguridad; Rust puede hacer mejor la mayoría de las cosas
→ C++: descartado por ser desordenado (mess); Rust puede hacer mejor la mayoría de las cosas
→ Clojure: modelado sobresaliente; es lo más parecido a Lisp; gran runtime sobre JVM
→ Elixir: gran runtime para despliegue y concurrencia; excelente experiencia de desarrollador; ecosistema relativamente pequeño
→ Erlang: gran runtime para despliegue y concurrencia; experiencia de desarrollador algo desafiante; ecosistema relativamente pequeño
→ Elm: prometedor; IBM está compartiendo buenos casos; ecosistema pequeño
→ Flow: mejora interesante sobre JS; pero los desarrolladores se están alejando
→ Go: excelente experiencia de desarrollador; excelente concurrencia; tuvo malas decisiones que volvieron extraño al lenguaje
→ Haskell: el mejor lenguaje funcional; comunidad de desarrolladores pequeña; no hay muchos casos de éxito en producción
→ Java: el mejor runtime; excelente ecosistema; experiencia de desarrollador regular
→ JavaScript: el lenguaje más popular; el ecosistema más amplio
→ Kotlin: mejora muchas cosas de Java; excelente respaldo de JetBrains; varios casos de éxito al pasar de Java a Kotlin
→ Python: el lenguaje más popular en administración de sistemas; buenas herramientas de análisis; buenos frameworks web; fue dejado de lado cuando Google eligió Go
→ Ruby: la mejor experiencia de desarrollador; los mejores frameworks web; gran comunidad; extremadamente lento; difícil de empaquetar
→ Rust: el mejor lenguaje nuevo; énfasis en Zero-cost abstractions (la abstracción no reduce la velocidad); énfasis en concurrencia; ecosistema relativamente pequeño; tiene límites en algunas optimizaciones del compilador (por ejemplo, el acceso directo a memoria debe ser
unsafe)→ TypeScript: añade tipos a JavaScript; excelente transpiler; los desarrolladores están pasando gradualmente de JS a TS; fuerte respaldo de Microsoft
Se decidió no elegir opciones basadas en VM (porque aumentan la complejidad)
Para el runtime más rápido, elegir JS y C
Para un runtime casi tan rápido como el mejor, elegir TypeScript y Rust
Si se hubiera elegido VM y framework web
→ Closer y Luminous
→ Java y Spring
→ Elixir y Phoenix