MÓDULO 1.2

✂️ Simplicidade Primeiro

Combater a tendência natural do LLM à superengenharia. Código mínimo que resolve. Sem features especulativas, sem abstrações inchadas, sem error handling para o impossível.

6
Tópicos
30
Minutos
Básico
Nível
Prática
Tipo
1

🎈 A doença da superengenharia

Karpathy: "Eles gostam muito de supercomplicar código e APIs, inchar abstrações, não limpar código morto... implementam uma construção inchada de 1000 linhas quando 100 bastariam." Esse é o vício mais difícil de quebrar.

🎯 Por que LLMs incham código

  • • Foram treinados em código "profissional" cheio de boilerplate.
  • • Confundem "linhas escritas" com "trabalho feito".
  • • Adicionam camadas para "parecerem completos".
  • • Não têm noção do custo de manutenção que estão criando.

✗ Versão inflada (típica)

class UserValidatorFactory { static create(config) { return new UserValidator( new RuleEngine(config.rules) ); } } const v = UserValidatorFactory .create({rules: [...]}); v.validate(user);

3 classes, 20 linhas, 1 caller.

✓ Versão honesta

if (!user.email || !user.name) { throw new Error('Invalid user'); }

2 linhas, mesmo efeito.

Volume ≠ Valor

Mais linhas raramente entrega mais. Geralmente entrega menos.

Complexidade essencial

Vem do problema. Aceite.

Complexidade acidental

Vem do código. Combata.

2

🚫 Sem features especulativas (YAGNI)

YAGNI = You Aren't Gonna Need It. Não adicione "por via das dúvidas" ou "para o futuro". Quase nada do que é feito assim acaba sendo usado, mas todos pagam o custo.

📊 Estatística que pesa

  • ~90% das "configurabilidades preventivas" nunca são usadas.
  • 100% delas precisam ser lidas, mantidas e testadas.
  • Custo médio: 3x mais código para resolver o mesmo problema.

✓ O que FAZER

  • Implementar exatamente o pedido
  • Hardcode valores até precisar variar
  • Adicionar parâmetros quando aparece o segundo caller
  • Mencionar futuro como comentário, não como código

✗ O que NÃO fazer

  • Parâmetros opcionais "para flexibilidade"
  • Hooks de extensão sem extensão prevista
  • "Suporte a múltiplos providers" com 1 provider
  • Feature flags para coisas que ainda não existem

💡 Regra prática

Se você consegue justificar uma feature só com "talvez", "no futuro", "caso queiramos" — corta. Quando o "caso" virar real, você adiciona em 5 minutos.

3

🧩 Abstrações de uso único

Abstrair com 1 caller é ruído. Abstrair com 2 callers é coincidência. Abstrair com 3 callers começa a fazer sentido. É a Rule of Three.

1

Primeiro uso: inline

Escreva direto. Não envolva em função.

2

Segundo uso: copia

Copy-paste. Sim, mesmo que pareça "errado". Não abstraia ainda.

3

Terceiro uso: agora sim

Agora você vê o padrão real. Abstraia com base nos 3 usos reais.

⚠️ Custo da abstração prematura

Abstração feita com 1 caller "achando" o padrão acaba modelando a coisa errada. Quando o segundo uso aparece, ele não cabe — e ou quebra o abstrato, ou cria-se um segundo abstrato pior.

É melhor ter duplicação por 10 minutos do que abstração errada por 10 anos.

4

⚠️ Erros impossíveis não merecem handler

Não envolver código em try/catch para cenários que não podem acontecer naquele contexto. Defensive coding excessivo esconde bugs reais.

✗ Defensive demais

function add(a, b) { if (a == null) return 0; if (b == null) return 0; if (typeof a !== 'number') return 0; if (typeof b !== 'number') return 0; try { return a + b; } catch (e) { return 0; } }

Esconde bugs reais com fallback silencioso.

✓ Direto

function add(a, b) { return a + b; }

Falha alto e cedo se algo errado chegar.

📋 Quando validação faz sentido

  • Boundary externa: input do usuário, API request, leitura de arquivo.
  • Interface pública: função exportada que outros times chamam.
  • Dado não confiável: deserialização, third-party.

Dentro do seu próprio módulo, com tipos definidos e callers conhecidos? Validação é teatro.

💡 Fail loud, fail fast

É melhor o programa explodir num lugar perto da causa do que retornar valor errado silenciosamente e estourar 5 funções depois.

5

📏 O teste do sênior

Antes de entregar, perguntar: "Um engenheiro sênior olharia esse código e diria 'isso pode ter metade do tamanho'?" Se a resposta é sim, simplifique.

🎯 Checklist do sênior (use antes de entregar)

  • ☐ Existe alguma classe/função com apenas 1 caller? → inline.
  • ☐ Tem parâmetro opcional usado em 1 lugar? → remove.
  • ☐ Tem try/catch que engole erro silenciosamente? → remove ou loga alto.
  • ☐ Tem comentário explicando o "que" em vez do "porquê"? → remove (o código fala).
  • ☐ Tem nome longo com prefixo redundante? (`UserUserService`) → renomeia.
  • ☐ Loop + map + filter + reduce em sequência? → talvez um único laço explícito.

🔧 Como pedir o teste do sênior no CLAUDE.md

Antes de finalizar qualquer mudança, releia o diff e responda: "Um sênior chamaria isso de complicado demais?" Se sim, simplifique e mostre antes/depois.
6

🔁 Quando 200 linhas viram 50

O segundo draft quase sempre é o bom. O primeiro draft é exploração; a reescrita é compressão. Pedir a reescrita explicitamente é mais barato do que aceitar o primeiro draft.

1

Draft 1: faz funcionar

Foco em correção. Pode ter sobras, repetição, verbosidade.

2

Draft 2: compressão

"Refaça mantendo o comportamento, mas em metade do tamanho." Surpresa: dá pra fazer.

3

Draft 3: polish

Nomes, casos de borda, comentários onde for não-óbvio. Pronto pra commit.

✓ Padrões de compressão

  • Early returns em vez de if/else aninhados
  • Operador ternário em atribuições simples
  • Eliminar variáveis temporárias usadas 1 vez
  • Funções helper viram inline quando têm 2 linhas

✗ Compressão ruim

  • One-liners ilegíveis com 5 operações
  • Remover nomes descritivos por curtos demais
  • Tirar comentários que explicavam "porquê"
  • Compressão que reduz performance significativa

💡 Prompt-mágico

"Releia o código. Se você pudesse reescrever em metade do tamanho mantendo legibilidade, faça. Mostre as duas versões."

📝Resumo do Módulo

Superengenharia — vício treinado, combatível com regras explícitas.
YAGNI — 90% das "flexibilidades" preventivas nunca usadas. Corte.
Rule of three — abstrair só no terceiro uso real.
Defensive coding — só na fronteira. Dentro confia. Falha alto.
Teste do sênior — checkpoint de 30s contra inchaço.
Segundo draft — sempre vale pedir compressão.

Próximo Módulo:

1.3 — 🔪 Mudanças Cirúrgicas