O que é escrevendo para o futuro e por que isso importa na prática
A maioria dos desenvolvedores que eu conheci passou pelo menos uma vez na carreira enfrentando um código que não entendia e que tinha sido escrito por eles mesmos três anos antes. Esse fenômeno tem nome: é a diferença entre escrever código para ser lido agora versus escrever código pensando em quem vai manter depois. A expressão escrevendo para o futuro descreve justamente essa disciplina técnica de documentar decisões, assumir formas claras de API e evitar abstrações precoces que só geram dor de cabeça em manutenção. Eu perdi duas semanas refatorando um módulo de cache em 2019 porque o colega que o escreveu havia adotado uma estratégia de serialização customizada sem documentar porquê. O código funcionava. O problema era que ninguém sabia qual formato de dados ele esperava quando os objetos eram armazenados em disco. A solução que encontrei foi escrever um parser reverso baseado em heurísticas de tipo, o que me custou cerca de 40 horas de trabalho. Se tivesse uma nota de design naquela classe, tudo teria levado 30 minutos.
Os princípios básicos do escrevendo para o futuro
O conceito se sustenta em três práticas observáveis. Primeiro, documentação viva dentro do código, não em repositórios separados que ninguém atualiza. Comentários que explicam o porquê de uma decisão, não o que o código faz. Segundo, contratos explícitos de interface. Se uma função recebe um objeto com cinco campos obrigatórios, deixe isso claro no tipo ou na assinatura. Terceiro, versionamento de breaking changes. Se você vai mudar um comportamento público, assegure-se de que a nova versão não quebre consumidores existentes sem aviso prévio. A parte mais contra-intuitiva que eu aprendi na prática é que documentar excessivamente também é ruim. Já vi equipes que gastavam 60% do tempo escrevendo comentários explicativos para 40% de tempo escrevendo código novo. O sweet spot real está em torno de 15 a 20% do tempo total do sprint. Qualquer coisa acima disso geralmente indica que o código em si está confuso o suficiente para precisar de muletas verbais.
Como implementar na prática
Comece com revisões de pull request focadas em clareza, não em funcionalidade. Isso significa questionar se uma variável com nome genérico como temp ou data deveria ter um identificador mais descritivo. Eu recomendo uma regra simples: qualquer variável ou função que precise de comentário explicativo no corpo do código provavelmente tem um nome inadequado. Renomeie primeiro, comente depois. O segundo passo é estabelecer convenções de commit semântico. Usar fix: para correções, feat: para novas funcionalidades, docs: para alterações de documentação. Isso permite gerar changelogs automaticamente e ajuda a entender o histórico de mudanças sem precisar abrir cada commit individualmente. Times que adotaram essa prática relataram redução de 30% no tempo médio de onboarding de novos desenvolvedores.
O terceiro ponto é criar templates de documentação de design decisions, também conhecidos como Architecture Decision Records ou ADRs. Um ADR típico contém: contexto do problema, decisões consideradas, decisão tomada, consequências e estado atual. Eu uso um template fixo de quatro campos que leva cerca de 15 minutos para preencher. Isso evita a tentação de escrever ensaios de dez páginas que ninguém lê.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Erros comuns que preciso corrigir regularmente
O erro número um é documentar apenas o positivo. Quando você toma uma decisão arquitetural, anote também as opções que foram rejeitadas e o motivo. Sem isso, desenvolvedores futuros vão reincidir nos mesmos erros porque não sabem por que certas abordagens foram descartadas. Eu vejo isso acontecendo repetidamente em projetos legados onde decisões de 2015 ainda são questionadas em 2024. O erro número dois é confiar em documentação externa mantida por terceiros. Páginas da wiki, READMEs manuais, documentos PDF. Todos esses formatos tendem a defasagem porque não estão atrelados ao ciclo de vida do código. Uma prática mais eficaz é manter documentação dentro do próprio repositório, preferencialmente em arquivos Markdown lado a lado com o código relevante.
Limitações e quando isso não funciona
O conceito de escrever pensando no futuro não se aplica a protótipos rápidos ou proof-of-concepts. Nesses casos, a velocidade de iteração supera qualquer benefício de documentação. Eu pessoalmente prefiro adiar qualquer esforço de Clareza de Design até o momento em que um prototype mostra trações reais e se torna candidato a produção. Outro cenário onde essa abordagem falha é em equipes muito pequenas, abaixo de três pessoas. Nesses casos, a comunicação informal resolve a maior parte dos problemas de entendimento. Documentação adicional pode até atrapalhar, criando a falsa sensação de que o conhecimento está preservado quando na verdade está disperso em arquivos que ninguém consulta.
Existe ainda o problema de over-engineering de documentação. Já vi sistemas onde cada método tinha uma seção de "Comportamento Esperado" de duas páginas, mas o código em si era ambíguo. Nesse caso, a documentação cria ruído em vez de sinal. A solução que funcionou foi simplificar para três frases por método máximo, forçando o time a resolver a ambiguidade no código antes de qualquer descrição textual.
Alternativas quando o escrevendo para o futuro é inviável
Em projetos com prazo apertado e requisitos voláteis, uma alternativa prática é adotar testes automatizados como documentação executável. Testes bem escritos explicam o comportamento esperado do código melhor que qualquer comentário. Eu recomendo pelo menos 70% de cobertura de teste para unidades críticas de negócio, e 100% para APIs públicas expostas a consumidores externos. Quando mesmo testes não são viáveis, pelo menos mantenha logs estruturados de auditoria. Registros de mudanças com timestamps, autores e justificativas breves permitem reconstruir o contexto histórico mesmo sem documentação formal. Isso não substitui boas práticas de escrita, mas serve como rede de segurança quando os prazos apertam.