De um sistema que dá medo a um sistema que dá para mudar.
Publicado em 14 de outubro de 2026
A reescrita é tentadora por bons motivos
Quando um sistema é difícil de mudar, a reescrita parece um alívio: um recomeço limpo, ferramentas modernas, nenhum histórico. Os motivos para querer isso costumam ser reais. Os riscos também. Uma reescrita precisa reproduzir, antes de poder substituir, todo o comportamento que o sistema antigo acumulou, boa parte sem documentação porque nunca foi uma decisão, apenas um conserto. Enquanto isso, o negócio não para, então o sistema antigo continua mudando e o alvo continua se movendo.
Nada disso significa que reescrever nunca é a resposta certa. Significa que o argumento a favor deve ser feito contra a alternativa de evoluir o que existe, com os custos de ambas por escrito. Na maioria das vezes, o caminho evolutivo é mais barato de começar, mais fácil de interromper e entrega valor mais cedo.
Encontre as fronteiras
Uma fronteira é um ponto em que você consegue mudar o comportamento sem editar tudo ao redor. Em um sistema existente, as fronteiras raramente estão onde o diagrama diz. Elas se descobrem acompanhando a mudança: quais partes sempre mudam juntas, quais partes ninguém ousa tocar, quais interfaces concentram mais tráfego ou mais incidentes.
Depois de identificada, torne a fronteira explícita. Coloque um contrato em volta dela: uma definição de API, um esquema de mensagens ou, no mínimo, um conjunto de testes de caracterização que registre o que o código faz hoje. A partir daí, os dois lados podem mudar de forma independente enquanto o contrato for respeitado, e uma verificação que falha avisa quando ele não for.
O padrão strangler decorre disso. O novo comportamento é construído atrás da fronteira enquanto a implementação antiga continua atendendo o tráfego, e a responsabilidade vai migrando fatia por fatia. Funciona porque cada fatia é pequena o bastante para ser concluída.
Torne cada mudança reversível
A propriedade mais útil de uma migração evolutiva é poder parar ou voltar atrás. Isso não acontece por acaso. Vem de alguns hábitos.
Feature flags ou regras de roteamento permitem que o código novo rode para uma fração do tráfego, ou para um único cliente, antes de rodar para todos. Executar os caminhos antigo e novo em paralelo e comparar os resultados revela diferenças que você não previu. Mudanças em banco de dados seguem a sequência expandir e contrair: adiciona-se a nova estrutura, grava-se nas duas, migram-se os leitores e só então se remove a estrutura antiga, de modo que cada passo possa ser desfeito.
O teste de um release é simples: alguém realmente o reverteu em um ambiente de teste? Se o caminho de rollback nunca foi exercitado, ele é uma teoria.
Registre o porquê, não só o quê
A arquitetura se desgasta quando o raciocínio se perde. Uma pessoa nova na equipe vê uma fronteira estranha, presume que foi acidente e a remove. Registros leves de decisão de arquitetura evitam isso. Cada um descreve o contexto, a decisão, as alternativas consideradas e as consequências aceitas, em uma página ou menos, guardado junto ao código.
Os registros também tornam a discordância produtiva. Quando uma decisão deixa de servir, a equipe consegue ver qual premissa mudou e substituir o registro, em vez de se afastar dele em silêncio.
Quando reescrever é a decisão certa
Às vezes é. A plataforma pode estar sem suporte, o modelo de dados pode estar fundamentalmente errado para o negócio, ou o custo de cada mudança pode ser dominado por algo que nenhuma fronteira consegue isolar. Mesmo assim, as mesmas técnicas valem: definir o contrato que o novo sistema precisa respeitar, migrar em fatias quando possível, rodar os dois em paralelo e manter a saída aberta.
Se você está pesando as opções, um diagnóstico independente do sistema atual costuma ser o passo mais barato. Ele transforma uma discussão de gosto em uma comparação de custos e riscos.