Pular para o conteúdo
Engenharia de Software

Divida Tecnica: Como Codigo Legado Vira

Divida tecnica e o Y2K de todo sistema: voce sabe que esta la, sabe que vai cobrar, e continua adiando. Ate que nao da mais pra adiar. Esse

TL;DR

Divida tecnica e o Y2K de todo sistema: voce sabe que esta la, sabe que vai cobrar, e continua adiando. Ate que nao da mais pra adiar. Esse artigo cobre como identificar onde a bomba esta e como desarma-la antes que exploda em producao.

Por que isso importa

O Y2K custou entre 300 e 600 bilhoes de dolares globalmente para corrigir. O bug do Ariane 5 foi causado por codigo copiado sem revisao das suposicoes do contexto original. O Knight Capital foi derrubado por codigo morto acumulado no sistema. Divida tecnica nao e um problema abstrato de qualidade: e a condicao que os bugs catastroficos precisam para acontecer.

De Onde Vem a Divida Tecnica

Ward Cunningham, que cunhou o termo divida tecnica nos anos 90, tinha uma analogia financeira precisa. Da mesma forma que divida financeira e legitima quando voce precisa de capital agora e tem capacidade de pagar depois, divida tecnica e legitima quando voce precisa chegar ao mercado antes do concorrente e tem capacidade de refatorar depois. O problema e que poucos times calculam a taxa de juros antes de contrair a divida.

Existem varios tipos de divida tecnica com origens diferentes. Divida deliberada e consciente, como usar uma biblioteca provisoria sabendo que vai ser substituida depois, e gerenciavel se for documentada. Divida deliberada inconsciente, como adotar uma arquitetura sem saber que ela vai ser dificil de escalar, e mais comum do que parece. Divida inadvertida e a que surge de boas praticas que existiam quando o codigo foi escrito mas que a industria superou, como codigo correto em 2010 que usa bibliotecas sem mais manutencao ativa em 2026.

A categoria mais perigosa e a divida acumulada por omissao: ninguem decidiu contrair divida, ela foi se acumulando por pequenas decisoes de nao documentar, nao testar, nao atualizar dependencias e nao refatorar quando o codigo ficou mais complexo do que deveria. Essa divida nao tem historico de raciocinio, nao tem data de vencimento e nao tem responsavel claro. E a que mais frequentemente aparece como causa raiz em post-mortems de falhas catastroficas.

Como Divida Tecnica Cria Bugs Catastroficos

O mecanismo e sempre parecido: o sistema sobrevive mais tempo do que as suposicoes originais esperavam. No Ariane 5, o codigo de navegacao foi escrito para os limites de velocidade do Ariane 4. A divida era a ausencia de documentacao das suposicoes de range dos valores. Quando o contexto mudou e o codigo foi reutilizado, ninguem sabia que havia suposicoes de range para verificar.

No Knight Capital, a divida era codigo morto com uma flag de ativacao que ninguem tinha removido porque remover codigo morto nao era prioridade. O custo de nao remover pareceu zero ate que se tornou 440 milhoes de dolares em 45 minutos. No Y2K, a divida era a decisao de armazenar o ano com dois digitos, razoavel em 1965 quando memoria era cara, que acumulou por 35 anos sem que ninguem fizesse o calculo de quanto custaria quando chegasse ao vencimento.

O padrao comum: suposicoes nao documentadas que se tornam invalidas com o tempo, mais a pressao de nao tocar em codigo que funciona, mais a perda de contexto conforme as pessoas que escreveram o codigo original saem. Cada um desses fatores sozinho e gerenciavel. Os tres juntos criam a condicao para falhas que parecem inexplicaveis de fora mas sao completamente compreensíveis quando se conhece a historia do sistema.

Como Identificar Divida Tecnica de Alto Risco

Nem toda divida tecnica e igualmente perigosa. A prioridade deve ser inversamente proporcional ao conhecimento disponivel sobre o codigo e diretamente proporcional ao impacto de uma falha. Codigo antigo com documentacao detalhada de suas suposicoes e menos perigoso do que codigo recente sem nenhuma documentacao, mesmo que o codigo antigo seja mais complexo.

Sinais de divida tecnica de alto risco

  • Codigo que ninguem no time atual sabe explicar por que foi escrito assim
  • Dependencias sem manutencao ativa ha mais de 2 anos
  • Codigo morto que ainda esta no repositorio porque 'pode ser util'
  • Conversoes de tipo ou operacoes aritmeticas sem comentarios sobre limites esperados
  • Suposicoes sobre escala de dados que eram verdadeiras quando o sistema foi criado mas podem nao ser mais
  • Areas do codigo com alta frequencia de bugs historicos sem refatoracao correspondente
  • Integrações com sistemas externos que nao tem contrato formal de interface documentado
  • Codigo que so alguem especifico consegue modificar com segurança

Estrategias Para Pagar a Divida sem Parar o Sistema

A reescrita total e a estrategia mais sedutora e frequentemente a mais perigosa. Joel Spolsky chamou de a coisa mais idiota que um time de software pode fazer. O sistema legado, por mais feio que seja, contem anos de aprendizado sobre casos de borda, regras de negocio implicitas e comportamentos que os usuarios dependem sem saber. Uma reescrita do zero nao herda esse conhecimento, e frequentemente replica os mesmos bugs originais enquanto adiciona bugs novos.

A estrategia do strangler fig, popularizada por Martin Fowler, e mais segura: construir o sistema novo em paralelo ao sistema antigo, roteando gradualmente o trafego para o novo conforme ele e verificado. Cada modulo migrado reduz a superfície do sistema legado sem criar um momento de corte abrupto. O sistema antigo e eventualmente estrangulado pelo novo sem que ninguem tenha passado por um big bang migration.

Para divida tecnica que nao justifica reescrita mas precisa ser gerenciada, a pratica mais eficaz e a regra do escoteiro: sempre deixe o codigo um pouco melhor do que encontrou. Cada pull request que toca uma area de divida tecnica inclui uma pequena melhoria: renomear uma variavel obscura, adicionar um comentario sobre uma suposicao, remover um bloco morto, adicionar um teste para um caminho nao coberto. Esse processo nao paga a divida rapidamente, mas para o acumulo e reduz o risco gradualmente sem impacto nas entregas.

Como apresentar divida tecnica para gestao nao tecnica?

A linguagem que funciona e a de risco e custo de manutencao, nao de qualidade de codigo. Exemplos concretos ajudam mais do que metricas abstratas: 'esse modulo tem causado 3 incidentes de producao nos ultimos 6 meses, cada um custando em media X horas de engenharia para resolver' e mais convincente do que 'esse modulo tem alta complexidade ciclomatica'. A analogia financeira funciona bem: divida tecnica e como divida financeira, tem taxa de juros que se manifesta como velocidade de desenvolvimento decrescente e frequencia crescente de incidentes. Pagar agora e mais barato do que pagar depois com juros.

Quando vale a pena contrair divida tecnica conscientemente?

Vale quando o prazo de vencimento e claro, o custo de pagar e aceitavel, e a decisao e documentada. Um startup que precisa lançar em 2 semanas para nao perder uma janela de mercado pode conscientemente usar uma solucao provisoria com o compromisso explicito de refatorar apos o lancamento. Isso e diferente de usar solucao provisoria sem data de refatoracao. A diferenca entre divida gerenciavel e divida catastrofica e quase sempre a documentacao da decisao: saber que a divida existe, saber por que foi contraida e saber quando precisa ser paga. Sem essa documentacao, a divida e invisivel ate que cause um problema que nao e mais invisivel.