Nomes que mentem: o problema mais comum em bases de código antigas

1. Por que nomes importam: a linguagem do código como documentação viva

1.1. O custo de um nome enganoso: horas de debug e suposições erradas

Em bases de código antigas, o maior vilão não é tecnologia obsoleta ou falta de testes — são nomes que mentem. Um nome enganoso pode custar horas de debug para uma equipe inteira. Considere este exemplo clássico:

function processData(input) {
    // 200 linhas depois...
    // O nome sugere processamento, mas na verdade envia e-mail
    enviarEmail(input);
    return true;
}

O desenvolvedor que chama processData espera processamento de dados, não efeitos colaterais de envio de e-mail. O resultado? Bugs intermitentes, suposições erradas e retrabalho.

1.2. Código lido 10x mais do que escrito: a carga cognitiva de desvendar intenções

Estima-se que código é lido cerca de 10 vezes mais do que escrito. Cada nome mentiroso força o leitor a abrir a implementação para descobrir o que realmente acontece. Isso quebra o fluxo de leitura e aumenta a carga cognitiva.

// Nome que mente: parece que valida, mas na verdade modifica estado
function isValid(user) {
    user.ultimoAcesso = new Date();  // Efeito colateral!
    return user.ativo && !user.bloqueado;
}

1.3. A diferença entre um nome descritivo e um nome "técnico" que esconde o propósito

Nomes descritivos revelam intenção; nomes "técnicos" escondem propósito. Compare:

// Nome técnico que mente: foca no "como", não no "quê"
function somarPesoEViaCep(itens, cep) { ... }

// Nome descritivo: foca no "quê"
function calcularFrete(itens, cep) { ... }

2. As três categorias clássicas de nomes que mentem

2.1. Nomes genéricos demais

data, info, temp, manager — esses nomes são tão vagos que não comunicam absolutamente nada:

function saveData(data) {
    // Que dados? Salvar onde? Em banco, arquivo, cache?
    banco.insert('logs', data);
}

2.2. Nomes que viraram sinônimos de outra coisa

O nome diz uma coisa, a implementação faz outra:

function getUsers() {
    // "get" sugere leitura, mas aqui há escrita
    const usuarios = api.fetch('/users');
    cache.set('usuarios', usuarios);  // Efeito colateral não documentado
    return usuarios;
}

2.3. Nomes que ficaram para trás em refatorações

Refatorações mal documentadas criam nomes órfãos:

function deleteTempFiles() {
    // Antigamente deletava, agora apenas arquiva
    moverParaLixeira('/tmp/arquivos');
    registrarAuditoria('Arquivos arquivados');
}

3. O efeito dominó: como um nome mentiroso contamina o sistema inteiro

3.1. Propagação de suposições incorretas

Quando um nome mente, a mentira se propaga:

// Módulo A: função com nome enganoso
function getTaxa() { return calcularTaxaComDesconto(); }

// Módulo B: assume que é taxa bruta
function calcularTotal(valor) {
    return valor * getTaxa();  // Erro! Já tem desconto aplicado
}

3.2. A síndrome do "funciona, mas ninguém sabe por quê"

Nomes que mentem criam código que funciona por coincidência:

function validateOrder(order) {
    // Nome sugere validação, mas também aplica regras de negócio
    order.desconto = order.valor > 100 ? 0.1 : 0;
    return order.valor > 0;
}

3.3. Quando a mentira vira "verdade"

Novos desenvolvedores codificam baseados no nome, não na implementação:

// Time assume que "cache" é rápido, mas na verdade é chamada HTTP
function getCachedData(key) {
    return http.get(`https://api.externa.com/cache/${key}`);
}

4. Técnicas práticas para detectar nomes mentirosos em bases legadas

4.1. Análise de frequência

Busque funções cujo nome não corresponde ao uso real:

# Grep reverso: onde "getUser" é chamado sem esperar efeitos colaterais?
grep -r "getUser" src/ | grep -v "await\|\.then"

4.2. O teste do "leigo"

Chame um colega não familiarizado com o módulo e pergunte: "O que essa função faz baseado apenas no nome?" Se ele errar, o nome mente.

4.3. Ferramentas de busca e grep reverso

# Encontre funções com "delete" no nome que não deletam
grep -r "def delete\|function delete" src/ | while read line; do
    if ! grep -q "delete\|remove\|drop" <<< "$line"; then
        echo "Possível mentira: $line"
    fi
done

5. Quando corrigir (e quando não): priorizando renomeações com impacto

5.1. O dilema do refactor: renomear quebra contratos de API?

Estratégias seguras incluem aliases e depreciação:

// Função antiga (depreciada)
function getUsersOld() {
    return getUsersNew();
}

// Nova função com nome correto
function fetchUsers() {
    return api.get('/users');
}

5.2. Prioridade máxima: nomes em interfaces públicas

Interfaces públicas que outros times consomem merecem atenção imediata:

// Endpoint público com nome enganoso
// GET /api/obter-usuarios  → na verdade retorna apenas admins
// Correção: criar novo endpoint e depreciar o antigo
// GET /api/obter-admins

5.3. Quando aceitar o nome mentiroso

Código morto, prestes a ser substituído, ou sem cobertura de testes:

// Código legado sem testes e prestes a ser substituído
// Aceitamos o nome mentiroso temporariamente
function getOldData() { ... }  // Não tocar, será removido mês que vem

6. Estratégia de migração gradual: como desmentir nomes sem parar o time

6.1. Criação de "pontes semânticas"

Novo nome + wrapper com log de aviso:

// Ponte semântica
function calcularTotalComDesconto(pedido) {
    console.warn('DEPRECIADO: use calcularTotal()');
    return calcularTotal(pedido);
}

function calcularTotal(pedido) {
    return pedido.itens.reduce((acc, item) => acc + item.preco, 0);
}

6.2. Renomeação em camadas

  1. Variáveis locais → 2. Funções internas → 3. APIs públicas
// Passo 1: Renomear variável local
function processar() {
    const dadosCliente = obterDados();  // Antes: "data"
}

// Passo 2: Renomear função interna
function obterDadosCliente() { ... }  // Antes: "getData"

// Passo 3: Renomear API pública (com bridge)
function obterDadosCliente() { ... }
function getData() { return obterDadosCliente(); }  // Bridge

6.3. Uso de lint personalizado

# Regra de lint: bloquear nomes vagos sem descrição
# .eslintrc.json
{
    "rules": {
        "id-denylist": ["error", "data", "info", "temp", "manager", "utils"]
    }
}

7. Prevenção: como evitar que novos nomes mentirosos entrem na base

7.1. Code review com checklist específico de nomenclatura

Checklist de code review:
- [ ] O nome descreve o quê, não o como?
- [ ] O nome revela efeitos colaterais?
- [ ] Um júnior entenderia o propósito?

7.2. Nomeie por intenção, não por implementação

// Ruim: foca na implementação
function somarPesoEViaCep(itens, cep) { ... }

// Bom: foca na intenção
function calcularFrete(itens, cep) { ... }

7.3. Cultura de "nomeie como se fosse explicar para um júnior amanhã"

// Se você precisa explicar o que a função faz, o nome está errado
function process() { /* ... */ }  // Ruim
function gerarRelatorioMensal() { /* ... */ }  // Bom

Referências