Pular para o conteúdo

No Clean Code, uma frase forte guia este tópico: comentários muitas vezes existem porque o código não conseguiu se explicar sozinho.

Isso não quer dizer “nunca comente”. Quer dizer:

  • prefira melhorar nomes, extrair funções e reduzir complexidade;
  • use comentários quando eles adicionam informação que o código não consegue expressar com clareza.

Quando o código é confuso, comentários viram “narrador” de um caos que continua caótico.

Ruim (comentário tenta explicar uma condição difícil):

// Verifica se o funcionário é elegível para benefícios completos
if ((employee.flags & HOURLY_FLAG) && (employee.age < 65)) { /* ... */ }

Melhor (o código passa a comunicar intenção):

if (employee.isEligibleForFullBenefits()) { /* ... */ }

Se possível:

  • substitua flags por métodos/enum;
  • encapsule regras em objetos de domínio.

Às vezes é obrigatório por compliance (projetos open source, empresas, órgãos públicos). Preferências:

  • padronizar cabeçalho de licença via ferramentas/IDE;
  • centralizar termos completos em arquivo próprio (ex.: LICENSE), quando permitido.

O comentário aqui não é “para explicar código”, é documentação jurídica.

2) Explicação de intenção (o “porquê”, não o “como”)

Seção intitulada “2) Explicação de intenção (o “porquê”, não o “como”)”

Um bom comentário responde “por que isso existe assim?”.

Exemplo:

// Substituímos espaços por %20 para evitar URL inválida em integrações legadas
String url = rawUrl.replaceAll("\\s+", "%20");

Se o “porquê” puder virar código (por exemplo, método encodeForLegacyUrl()), melhor ainda.

Quando há risco real de alguém “otimizar” e causar incidente, um comentário pode prevenir.

// Não paralelizar: esta rotina depende da ordem para garantir consistência no arquivo final.
processRecordsInOrder(records);

Use com parcimônia. Se é crítico, considere também:

  • testes que quebrem quando a ordem muda;
  • invariantes no código (ex.: validações).

Comentários TODO são úteis quando:

  • têm contexto;
  • têm critério de conclusão;
  • idealmente têm referência (issue/ticket).

Exemplo:

// TODO(#123): substituir regex por API de URI quando removida compatibilidade com sistema X.

Evite TODOs vagos como “arrumar isso depois” (viram lixo eterno).

Quando o código é usado por outras pessoas/equipes, Javadoc pode ser essencial:

  • propósito do método/classe;
  • contratos: pré-condições e pós-condições;
  • exceções lançadas e quando.

Exemplo:

/**
* Calcula o imposto com base nas faixas vigentes.
* @param salario salário bruto mensal, deve ser >= 0
* @return valor do imposto a recolher
* @throws IllegalArgumentException se salario < 0
*/
public BigDecimal calcularImposto(BigDecimal salario) { /* ... */ }

Observação: Javadoc desatualizado é pior que ausência. Use quando você consegue manter.

Murmúrios (opiniões, desabafos, “história pessoal”)

Seção intitulada “Murmúrios (opiniões, desabafos, “história pessoal”)”

Comentários como “não sei por que isso funciona” ou “gambiarra” não ajudam o leitor a entender o sistema. Se há risco técnico, o correto é:

  • explicar o motivo real e o impacto;
  • ou criar um ticket e registrar.

Se o comentário apenas repete o que o código já diz, ele vira ruído.

Ruim:

// incrementa i
i++;

Melhor: não comentar.

Em ambiente de aprendizagem, redundâncias aparecem por hábito. Em código profissional, atrapalham.

São perigosos porque geram confiança falsa. Exemplo clássico:

  • comentário diz “ordena por data”, mas o código ordena por nome.

Regra: se o comentário não consegue ser mantido, ele deve ser removido ou reescrito (ou o código deve ser ajustado para cumprir o contrato).

Com exceção de documentação de API, comentários que tentam impor regras podem virar “leis sem fiscalização”.

Se algo é realmente obrigatório:

  • use validações;
  • use testes;
  • use lint/formatters;
  • ou regras de CI.

Blocos enormes explicando configuração e operação normalmente indicam:

  • falta de documentação externa (README, docs, runbook);
  • responsabilidades misturadas no código.

Preferências:

  • documentar em docs/ ou wiki do projeto;
  • manter o comentário curto com link para a doc.

Comentários a cada linha quebram o fluxo de leitura. Se “precisa comentar tudo”, geralmente:

  • funções estão longas;
  • nomes estão ruins;
  • há lógica demais no mesmo lugar.

A correção típica é refatorar: extrair funções e renomear.

Evite “seções” artificiais:

// ------- GETTERS -------
// ------- SETTERS -------

Se uma classe precisa de banners para ser entendida, ela provavelmente está grande demais.

  • divida em classes menores;
  • use encapsulamento;
  • mantenha foco.

Comentários no fim da linha geralmente são menos legíveis:

return sdf.format(date); // formato padrão é "dd/MM/yyyy"

Prefira colocar acima, ou, melhor ainda, explicitar no código:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
return sdf.format(date);

(Perceba: aqui a melhor solução foi remover necessidade do comentário tornando o código explícito.)

Não registre “Autor, data, linhas editadas” no arquivo. Git já faz isso melhor:

  • git blame
  • histórico de commits
  • PRs e reviews

Isso evita comentários obsoletos e reduz ruído.

Técnica principal: substitua comentários por código melhor

Seção intitulada “Técnica principal: substitua comentários por código melhor”

Quando você sentir vontade de comentar “o que está acontecendo”, tente primeiro:

  1. Renomear variáveis/métodos
    De:
int d;

Para:

int daysSinceLastLogin;
  1. Extrair função com nome explicativo
    De:
if (salario <= 2500) { return 0; }

Para:

if (isIsento(salario)) { return BigDecimal.ZERO; }
  1. Introduzir objeto/enum de domínio
    Em vez de flags e números mágicos, use tipos que carregam significado.

Exemplo completo: refatorando “comentários demais”

Seção intitulada “Exemplo completo: refatorando “comentários demais””

Ruim:

// Calcula o imposto de renda de um funcionário
// Retorna o valor do imposto calculado
public double calcularImpostoDeRenda(double salario) {
// Primeiro verifica se o salário é maior que o limite de isenção
// Depois calcula o imposto com base na faixa salarial
if (salario <= 2500) {
return 0; // Isento de imposto
} else if (salario <= 5000) {
return salario * 0.1; // 10% de imposto
} else {
return salario * 0.2; // 20% de imposto
}
}

Melhor (menos comentário, mais intenção no código):

public double calcularImpostoDeRenda(double salario) {
if (isIsento(salario)) return 0.0;
if (isFaixaIntermediaria(salario)) return calcularImpostoFaixaIntermediaria(salario);
return calcularImpostoFaixaSuperior(salario);
}

O comentário deixou de ser necessário porque a estrutura e os nomes explicam a regra.

Antes de escrever um comentário, pergunte:

  • Posso tornar o código óbvio com um nome melhor?
  • Posso extrair uma função para reduzir complexidade?
  • O comentário explica o “porquê” (intenção/risco) e não só o “como”?
  • Se alguém mudar o código, esse comentário tem grande chance de ficar desatualizado?
  • Isso deveria estar em documentação externa (README/runbook) em vez de dentro do código?
  • Robert C. Martin, Clean Code (capítulo sobre Comments)
  • Boas práticas de Javadoc (Oracle Java Documentation)
  • Convenções de TODO e rastreabilidade (issues/tickets)