Introdução: O Código que "Venceu"
Você já abriu um arquivo de código e sentiu vontade de fechá-lo imediatamente? Aquela função de 300 linhas, cheia de if/else aninhados e nomes de variáveis como data1 e temp. Todos nós já estivemos lá.
Muitos desenvolvedores acreditam que, se o código está funcionando, não devemos tocá-lo. Mas, no mundo real do desenvolvimento de software, código que não evolui, apodrece. É aqui que entra o Refactoring (Refatoração).
O que é, afinal, a Refatoração?
Refatorar não é "reescrever o sistema". Segundo Martin Fowler, um dos papas do assunto, refatoração é o processo de alterar um sistema de software de modo que não mude o comportamento externo do código, mas melhore sua estrutura interna.
Vamos ver um exemplo prático.
Substituindo Números Mágicos por Constantes
Para ilustrar como a refatoração pode ser simples e poderosa ao mesmo tempo, vamos olhar para o clássico problema dos 'números mágicos'. No exemplo abaixo, veja como a simples troca de um número solto por uma constante bem nomeada elimina a necessidade de comentários e torna a regra de negócio óbvia para qualquer um que ler o código pela primeira vez.
Antes
if ($user->role === 1) {
$bonus = $salario * 1.15;
}Depois
const ROLE_MANAGER = 1;
const BONUS_PERCENTAGE = 1.15;
if ($user->role === ROLE_MANAGER) {
$bonus = $salario * BONUS_PERCENTAGE;
}A regra de ouro: Se você mudou o que o código faz (corrigiu um bug ou adicionou uma feature), você não estava refatorando. Refatorar é puramente sobre design e legibilidade.
Por que você deve se importar? (Especialmente se for Júnior/Pleno)
Redução da Carga Cognitiva: Um código bem refatorado permite que você entenda a lógica em 5 segundos, em vez de 5 minutos.
Economia de Tempo (Dívida Técnica): O que você não limpa hoje, vira um obstáculo amanhã. O refactoring mantém a velocidade de entrega constante a longo prazo.
Profissionalismo: Escrever código que o computador entende é fácil. Escrever código que outros humanos entendem é o que diferencia um sênior.
Quando Refatorar? (A Regra dos Três)
Não se refatora "por esporte". Existe um momento certo:
Ao adicionar uma funcionalidade: Se o código atual dificulta a nova implementação, refatore primeiro para abrir caminho.
Ao corrigir um bug: Se o bug estava escondido, a estrutura provavelmente está confusa.
Code Review: É o momento perfeito para sugerir melhorias de clareza.
3 Técnicas Práticas para Começar Hoje
1. Extração de Método (Extract Method)
Você já sentiu que uma função está tentando fazer coisas demais ao mesmo tempo? Quando isso acontece, a lógica de negócio fica enterrada em detalhes de implementação. A Extração de Método serve para dar nome aos bois: transformamos blocos lógicos em pequenas funções auxiliares. Note como, no 'Depois', a função principal passa a contar uma história clara do que está acontecendo.
Antes
// Processa a lista de usuários
function notifyUsers(users) {
users.forEach(user => {
// Verifica se o usuário pode receber e-mail
if (user.active && user.emailVerified && !user.unsubscribed) {
sendEmail(user);
}
});
}Depois
function notifyUsers(users) {
users.filter(canReceiveEmail).forEach(sendEmail);
}
function canReceiveEmail(user) {
return user.active && user.emailVerified && !user.unsubscribed;
}2. Substituir Condicionais por Guard Clauses
Um dos maiores inimigos da legibilidade é o que chamamos de 'Efeito Pirâmide' — aquela sucessão infinita de if aninhados que empurra o código para a direita. A técnica de Guard Clauses propõe inverter essa lógica: validamos o erro e saímos da função o quanto antes. Compare como o fluxo de leitura deixa de ser um labirinto e passa a ser uma linha reta.
Antes
public function processarPagamento($pedido) {
if ($pedido->status !== 'pendente') {
if ($pedido->valor > 0) {
if ($pedido->cliente->temCartaoSalvo()) {
// Lógica principal de pagamento aqui...
return "Sucesso";
} else {
return "Erro: Sem cartão";
}
} else {
return "Erro: Valor inválido";
}
} else {
return "Erro: Pedido já processado";
}
}Depois
public function processarPagamento($pedido) {
if ($pedido->status === 'processado') return "Erro: Já processado";
if ($pedido->valor <= 0) return "Erro: Valor inválido";
if (!$pedido->cliente->cartao) return "Erro: Sem cartão";
// Lógica principal de pagamento aqui...
return "Sucesso";
}Percebeu como o código ficou linear? Agora você consegue ler a regra de negócio sem se perder nos colchetes.
3. Nomes que dizem a Verdade
Se uma variável se chama list, ela não diz nada. Se ela se chama expiredSubscriptions, ela conta uma história.
O Requisito Não Negociável: Testes
Você nunca refatora sem uma rede de segurança. Antes de mudar uma linha sequer, garanta que existam testes unitários cobrindo aquela funcionalidade. Se você mudar o código e o teste falhar, você quebrou o comportamento externo. Sem testes, você não está refatorando, está apenas "mexendo e torcendo".
Conclusão
Refactoring não é um evento único que acontece uma vez por ano. É um hábito diário. É deixar o código um pouco mais limpo do que você o encontrou. Isso não só ajuda o projeto, mas molda a sua mente para pensar de forma mais arquitetural.
E você? Qual foi a refatoração mais satisfatória (ou traumática) que já fez? Deixe nos comentários!
Comentar