Refatoracao e o processo de melhorar a estrutura interna do codigo sem alterar seu comportamento externo. Todo desenvolvedor trabalha com codigo legado — aprender a refatora-lo com seguranca e uma habilidade fundamental. Este guia mostra as tecnicas mais eficazes e como aplica-las sem medo.
Por que refatorar
Codigo mal estruturado custa caro: cada nova feature leva mais tempo, bugs sao dificeis de encontrar e corrigir, novos devs demoram para entender o sistema, mudanças em um lugar quebram coisas em outro.
Refatoracao e investimento: o custo e imediato, mas o retorno vem em semanas de desenvolvimento mais rapido, bugs menos frequentes e onboarding mais facil.
A regra de ouro: testes primeiro
NUNCA refatore sem testes. E a regra mais importante. Se o codigo legado nao tem testes, escreva testes que capturam o comportamento atual (characterization tests) ANTES de mudar qualquer coisa.
Characterization test: teste que documenta o comportamento existente, mesmo que voce nao saiba se o comportamento esta correto. O objetivo e detectar se a refatoracao mudou o comportamento.
def test_calcular_desconto_comportamento_atual():
# Nao sei se esta correto, mas e o comportamento atual
assert calcular_desconto(100, “VIP”) == 85.0
assert calcular_desconto(100, “normal”) == 100.0
assert calcular_desconto(0, “VIP”) == 0.0
assert calcular_desconto(-10, “VIP”) == -8.5 # Bug? Mas e o comportamento atual
Code smells: sinais de que precisa refatorar
Funcao/metodo longo: mais de 20-30 linhas geralmente pode ser quebrado. Classe grande (God Class): classe com muitas responsabilidades. Duplicacao: mesma logica copiada em multiplos lugares. Comentarios excessivos: se o codigo precisa de muitos comentarios para ser entendido, a estrutura pode ser melhorada. Feature Envy: metodo que usa mais atributos de outra classe do que da propria. Parametros demais: funcao com 5+ parametros geralmente indica falta de abstracao.
Tecnicas de refatoracao essenciais
Extract Method
A tecnica mais comum. Extraia blocos de codigo com uma responsabilidade clara para um metodo separado.
Antes:
def processar_pedido(pedido):
# Validar
if not pedido.itens:
raise ValueError(“Pedido sem itens”)
if pedido.valor_total 10000:
desconto = pedido.valor_total * 0.10
valor_final = pedido.valor_total – desconto
# Processar pagamento
resultado = gateway.cobrar(pedido.cliente.cartao, valor_final)
if not resultado.sucesso:
raise PagamentoFalhou(resultado.erro)
# Atualizar estoque
for item in pedido.itens:
estoque.reduzir(item.produto_id, item.quantidade)
Depois:
def processar_pedido(pedido):
validar_pedido(pedido)
valor_final = calcular_valor_com_desconto(pedido)
processar_pagamento(pedido.cliente, valor_final)
atualizar_estoque(pedido.itens)
Cada funcao extraida pode ser testada isoladamente.
Replace Conditional with Polymorphism
Substitua cadeias de if/elif/else por classes polimoricas:
Antes:
def calcular_frete(tipo, peso, distancia):
if tipo == “sedex”:
return peso * 2.5 + distancia * 0.8
elif tipo == “pac”:
return peso * 1.2 + distancia * 0.3
elif tipo == “transportadora”:
return peso * 3.0 + distancia * 1.5 + 50 # taxa fixa
…
Depois:
class FreteStrategy(ABC):
@abstractmethod
def calcular(self, peso, distancia):
pass
class FreteSedex(FreteStrategy):
def calcular(self, peso, distancia):
return peso * 2.5 + distancia * 0.8
class FretePAC(FreteStrategy):
def calcular(self, peso, distancia):
return peso * 1.2 + distancia * 0.3
Introduce Parameter Object
Quando muitos parametros viajam juntos, agrupe-os em um objeto:
Antes: def criar_usuario(nome, email, telefone, rua, numero, cidade, estado, cep)
Depois: def criar_usuario(dados_pessoais: DadosPessoais, endereco: Endereco)
Strangler Fig Pattern para sistemas grandes
Para refatorar um sistema inteiro sem reescrever do zero: coloque um proxy/router na frente do sistema legado. Para cada funcionalidade, crie a versao nova e redirecione o trafego. Gradualmente, cada parte do sistema legado e substituida. Quando nao resta mais trafego para o legado, descomissione-o.
Essa abordagem e mais segura que a temida “rewrite from scratch” que falha na maioria dos casos.
Regra do Boy Scout
“Deixe o codigo mais limpo do que voce encontrou.” Nao precisa refatorar tudo de uma vez. Cada vez que tocar em um arquivo, melhore algo pequeno: renomeie uma variavel confusa, extraia um metodo, remova codigo morto. Com o tempo, o codigo inteiro melhora organicamente.
Tem um projeto em mente?
Somos especialistas em transformar ideias em produtos digitais. Apps, sites, automações e IA — vamos construir juntos.