Por que escrever ADRs
(github.blog)ADR = Architecture Decision Records
Registrar na base de código por que decisões de arquitetura foram tomadas daquela forma.
O GitHub aplica isso nas equipes mobile de iOS/Android e este é um texto explicando por que isso é necessário
Não é para você, é para o seu eu do futuro
ADR não é um processo de reflexão sobre a decisão que tomei, e sim algo que ajuda a lembrar o mindset de quando essa arquitetura foi decidida, daqui a 6~12 meses.
O ADR captura o momento em que a decisão é tomada, incluindo até PoCs discutidas em reuniões/Zoom/Slack/código.
A ideia é tirar esse contexto que está na sua cabeça, colocar em palavras e depois conseguir recolocá-lo na cabeça quando você voltar a olhar essa arquitetura no futuro.
O verdadeiro bônus aparece quando, alguns meses depois, alguém vier te cobrar perguntando por que o módulo GitHubAPIClient funciona desse jeito.
Em vez de gastar 30 minutos fazendo pair para explicar o código, você pode simplesmente passar esse ADR e explicar as decisões tomadas durante a construção do módulo.
Não é para você, é para seus colegas
Um ADR deve ir além de uma explicação de uma linha como "este recurso é a implementação da feature-#3128".
É um formato de explicação mais longo que ajuda colegas a entender por que esse recurso foi feito desta forma e não de outra.
(Isso pode aparecer no ADR como "alternativas consideradas", "vantagens e desvantagens" etc.)
O que para você é simples pode ser complexo para seus colegas.
Se você dedicar um tempo para registrar o processo de pensamento por trás da decisão, dará aos membros da equipe a chance de entrar na sua cabeça.
Escrever ADRs torna possível a "socialização da decisão".
Assim, em vez de decisões serem tomadas individualmente, a equipe passa a tomar decisões pelas quais assume responsabilidade de manutenção.
Se você escrever o ADR antes de abrir o pull request, poderá receber melhores reviews de PR da equipe que o estiver avaliando.
Não é para você, é para seus futuros colegas
ADR não serve para mostrar o quanto você é inteligente nem para deixar as pessoas confusas ao olhar a arquitetura que você criou.
ADR ajuda novos membros da equipe, quando entram, a entender a base de código atual e como ela evoluiu ao longo do tempo.
À medida que a equipe se expande e cresce, os caminhos de comunicação entre os membros aumentam.
Registrar assim as decisões ajuda a comunicação também com as pessoas que entram depois, conforme a equipe cresce.
O melhor cenário é quando um membro da sua equipe escreve um novo ADR que substitui uma decisão que você tomou no passado, e no futuro você acaba aprendendo com seu colega.
"Escrevam mais ADRs. Sempre que nossa equipe cresce e a base de código fica mais complexa, ADRs são uma ótima forma de ajudar nosso eu do futuro, os membros atuais da equipe e os futuros membros da equipe."
3 comentários
Entre os casos famosos de governo eletrônico, o Gov.UK também tem um repositório que organiza os ADRs relacionados à sua arquitetura de nuvem na AWS.
https://github.com/alphagov/govuk-aws/…
Foi uma boa referência.
Exemplos de ADR
Decisão sobre framework CSS
https://github.com/joelparkerhenderson/architecture_decision_record/…
Premissa: como queremos criar um web app moderno, rápido e responsivo, não queremos usar jQuery
Restrição: um framework que não exija o uso de jQuery
Considerado: não usar nada, ou escolher entre Bootstrap/Bulma/Foundation/Materialize/Semantic UI; Bulma e Semantic UI foram os dois mais analisados
Monorepo vs Multirepo
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ Estamos usando git como SCM, então precisamos decidir entre monorepo vs polyrepo vs hybrid
→ Quando organização/time/projeto são pequenos e a iteração é rápida, Monorepo
→ Quando organização/time/projeto são grandes e a estabilidade é mais importante, Polyrepo
Decisão sobre linguagem de programação
https://github.com/joelparkerhenderson/architecture_decision_record/…
→ No frontend, TypeScript
→ No backend, Rust
→ O frontend é algo comum, mas precisa permitir desenvolvimento, deploy e iteração rápidos. Não há necessidade de compatibilidade com legado
→ O backend exige um nível um pouco acima do comum. Há considerações de qualidade, estabilidade e segurança. É necessário algo quase em tempo real (não pode haver pausas causadas por GC). Programação funcional / processamento paralelo e multicore, além de segurança de memória, também são importantes
Restrição: precisa necessariamente poder rodar em serverless de grandes serviços de nuvem (Amazon Lamba)
Considerado: C/C++/Clojure/Elixir/Erlang/Elm/Flow/Go/Haskell/Java/Javascript/Kotlin/Python/Ruby/Rust/TypeScript
Debate:
→ C: descartada por baixa segurança; Rust consegue fazer a maior parte das coisas melhor
→ C++: descartada por ser bagunçada (mess); Rust consegue fazer a maior parte das coisas melhor
→ Clojure: excelente modelagem; mais parecido com Lisp; ótimo runtime na JVM
→ Elixir: excelente runtime para deploy e concorrência; ótima experiência de desenvolvimento; ecossistema relativamente pequeno
→ Erlang: excelente runtime para deploy e concorrência; experiência de desenvolvimento um tanto desafiadora; ecossistema relativamente pequeno
→ Elm: promissora; a IBM está compartilhando bons casos; ecossistema pequeno
→ Flow: melhoria interessante para JS; mas os desenvolvedores estão se afastando
→ Go: ótima experiência de desenvolvimento; ótima concorrência; houve decisões ruins que deixaram a linguagem estranha
→ Haskell: a melhor linguagem funcional; comunidade de desenvolvedores pequena; não há muitos casos de sucesso em produção
→ Java: o melhor runtime; excelente ecossistema; experiência de desenvolvimento apenas razoável
→ JavaScript: a linguagem mais popular; o ecossistema mais amplo
→ Kotlin: melhora muitos pontos do Java; excelente apoio da JetBrains; vários casos de sucesso na migração de Java para Kotlin
→ Python: a linguagem mais popular na área de administração de sistemas; boas ferramentas de análise; bons frameworks web; acabou sendo deixada de lado quando o Google escolheu Go
→ Ruby: a melhor experiência de desenvolvimento; o melhor framework web; excelente comunidade; extremamente lenta; difícil de empacotar
→ Rust: a melhor linguagem nova; ênfase em Zero-cost abstractions (a abstração não reduz a velocidade); ênfase em concorrência; ecossistema relativamente pequeno; há limites em algumas otimizações do compilador (por exemplo, acesso direto à memória precisa ser
unsafe)→ TypeScript: adiciona tipos ao JavaScript; excelente transpiler; os desenvolvedores estão migrando gradualmente de JS para TS; forte apoio da Microsoft
Foi decidido não escolher opções baseadas em VM (porque isso aumenta a complexidade)
Para o runtime mais rápido, escolher JS e C
Para um runtime quase tão rápido quanto o melhor, escolher TypeScript e Rust
Se tivessem escolhido VM e framework web
→ Closer e Luminous
→ Java e Spring
→ Elixir e Phoenix