PrincípioIniciante6 min de leitura6 seções1999, Data aproximada

DRY, KISS e YAGNI

Três lembretes contra o excesso: DRY (não repita a mesma regra), KISS (não complique além do necessário) e YAGNI (não construa o que talvez nunca use). Parecem óbvios e são justamente por isso perigosos — DRY apressado acopla o que só parecia igual, e YAGNI mal lido vira desculpa para não pensar. O valor está em saber quando cada um se aplica.

Em 10 segundos

DRY, KISS e YAGNI são heurísticas contra o excesso, não leis. DRY é sobre não duplicar conhecimento (a mesma regra em dois lugares), e não sobre não duplicar texto — unir código que só coincide acopla o que devia ser independente. KISS pede a solução mais simples que funciona; YAGNI pede não construir o que talvez nunca venha. Todas dizem 'na dúvida, para este lado', não 'sempre'.

Antes de ter nome

KISS ('keep it simple, stupid') é atribuído ao engenheiro aeronáutico Kelly Johnson nos anos 1960, muito antes de virar mantra de software.

  • #principio
  • #simplicidade
  • #duplicacao
  • #over-engineering
Analogia

O canivete suíço que ninguém usa inteiro

Existe um canivete suíço com 87 ferramentas — e ninguém nunca usou o abridor de charuto embutido. Ele é pesado, caro e desconfortável justamente pelo que 'talvez um dia' seja útil. YAGNI é escolher o canivete de três lâminas que resolve 99% dos casos; KISS é preferir a faca simples quando você só vai cortar pão; e DRY é não ter três canivetes idênticos na mesma gaveta — mas também não fundir a chave de fenda com o saca-rolhas só porque os dois giram.

01Conceito

A duplicação que não era duplicação

O erro mais caro do DRY é unir código que só parecia igual. Dois trechos idênticos hoje podem representar regras diferentes que mudam por motivos diferentes — um desconto de RH e um imposto que por acaso são ambos 10%.

Unificá-los cria um acoplamento invisível: quando a alíquota fiscal muda e alguém edita a função 'compartilhada', o desconto de RH muda junto, sem ninguém pedir. A abstração errada é mais cara que a duplicação que ela tentou eliminar.

A regra prática é olhar o motivo da mudança, não a aparência do código — é o SRP disfarçado. Se dois trechos sempre vão mudar juntos, são o mesmo conhecimento: unifique. Se podem mudar por motivos independentes, são coincidência: deixe separados, mesmo que o código fique igual por enquanto.

Daí a regra dos três: espere a terceira repetição antes de abstrair. Com uma ocorrência não há duplicação; com duas, ainda não dá para saber qual parte é a regra e qual é o acidente; na terceira, o padrão real fica visível e a abstração acerta o recorte. Abstrair na primeira é adivinhar — e 'a abstração errada é muito mais cara que a duplicação', como resume Sandi Metz.

02No mundo real

Como isso aparece na prática

O framework interno que ninguém pediu

Cenário

Para 'evitar repetição no futuro', um time construiu um framework de configuração genérico antes do segundo caso de uso existir. Meses depois, o segundo caso não encaixava, e o framework foi contornado com gambiarras.

Como o padrão entra

O framework foi removido e o código voltou a resolver cada caso diretamente. A generalização só voltou a ser considerada quando surgiu o terceiro caso real, aí sim com o padrão claro.

Trade-off: Houve retrabalho de desmontar o que já existia. Em troca, o código ficou legível de novo, e a abstração futura passou a ser guiada por casos reais, não por adivinhação.

A função utilitária que acoplou dois mundos

Cenário

Um formatarValor compartilhado formatava tanto preços de produto quanto valores de relatório contábil. Um pedido do time contábil (casas decimais diferentes) quebrou a exibição de preços na loja.

Como o padrão entra

A função foi dividida em duas — formatarPreco e formatarValorContabil — apesar de o código ser quase idêntico, porque as duas mudam por motivos diferentes.

Trade-off: Voltou a existir código parecido em dois lugares. Em troca, cada contexto passou a evoluir sozinho, sem que uma mudança fiscal quebrasse a vitrine.

Passo a passoComo aplicar sem exagerar
  1. 1

    Olhar o motivo da mudança

    Dois trechos iguais mudam pelo mesmo motivo? É conhecimento duplicado. Mudam por motivos diferentes? É coincidência — deixe separado.

  2. 2

    Esperar a terceira repetição

    Com uma ou duas ocorrências, ainda não dá para acertar o recorte. Na terceira, o padrão real aparece e a abstração cabe.

  3. 3

    Extrair só o que é a mesma regra

    DRY une conhecimento, não texto. Unifique a regra de negócio compartilhada; não funda RH com fiscal porque ambos são 10%.

  4. 4

    Parar no mínimo que funciona

    KISS e YAGNI: resolva o problema de hoje. Generalize quando o terceiro caso real pedir — não antes.

O DRY que acoplou dois mundos

Compila, roda, passa no code review. E quebra depois.

Dois cálculos 'iguais' (desconto de RH e imposto) viram uma função única. O diff ficou menor — e uma mudança fiscal passa a alterar a política de RH sem ninguém pedir.

// Dois 10% "iguais" — DRY apressado unifica.
function aplicarDezPorcento(valor: number) {
  return valor * 0.1;
}

const descontoRH = aplicarDezPorcento(salario); // politica de RH
const imposto = aplicarDezPorcento(salario);    // regra fiscal

// Aliquota fiscal vira 12%. Alguem edita a funcao unica.
// Desconto de RH muda junto. A abstracao acoplou dois mundos.

O que quebra

  • Na reforma tributáriaEditar a função compartilhada muda o desconto de RH junto — bug silencioso em outro domínio.
  • No testeCobrir fiscal exige raciocinar sobre RH, porque os dois compartilham o mesmo ponto de mudança.
  • Na revisãoO nome genérico (aplicarDezPorcento) esconde que há duas regras de negócio distintas atrás.

A saída: Separe por motivo de mudança: descontoRH e impostoRetido podem parecer iguais e ainda assim ser conhecimento diferente. Unifique só o que sempre muda junto.

04Cuidado

Onde isto dá errado

  1. Aplicar DRY a texto, não a conhecimento

    Dois trechos iguais nem sempre são a mesma regra. Se eles mudam por motivos diferentes, unificá-los acopla o que devia ser independente, e uma mudança num contexto vaza para o outro sem aviso.

  2. Usar KISS para justificar o simplista

    Simples não é o mesmo que fácil. Espremer complexidade essencial (concorrência, falha, consistência) para 'ficar simples' só empurra o problema para produção, onde ele volta mais caro.

  3. Usar YAGNI contra requisito conhecido

    YAGNI vale para o que talvez venha, não para o que já se sabe que vem. Ignorar um requisito iminente em nome de 'você não vai precisar' é confundir simplicidade com míopia.

05Implementação

Duplicação legítima × falsa

// DRY diz: uma regra, um lugar. Mas cuidado com a FALSA duplicacao.

// Estes dois calculos SAO iguais hoje — e mudam pelo MESMO motivo:
function totalPedido(itens) { return itens.reduce((s, i) => s + i.preco, 0); }
// -> extrair para uma funcao unica e DRY legitimo.

// Estes dois PARECEM iguais, mas mudam por motivos DIFERENTES:
const descontoFuncionario = salario * 0.1;   // politica de RH
const impostoRetido       = salario * 0.1;   // regra fiscal
// -> unificar em "aplicar10Porcento" acopla RH a fiscal.
// Quando a aliquota fiscal mudar, o desconto de RH muda junto. Bug.

// A regra dos tres: so abstraia na TERCEIRA repeticao. Antes disso,
// voce ainda nao sabe se e a mesma regra ou uma coincidencia.
06Decisão

Quando usar × quando evitar

Use quando

3
  • DRY quando o mesmo conhecimento se espalha e muda junto.
  • KISS quando há solução mais simples para o mesmo problema.
  • YAGNI diante da vontade de generalizar sem caso real.

Evite quando

2
  • DRY quando a semelhança é coincidência.
  • YAGNI como desculpa contra requisito conhecido e iminente.

Testar o que ficou

3 armadilhas de DRY, KISS e YAGNI viram perguntas, com o nome do padrão escondido, misturadas com padrões parecidos.

Onde isto aparece de verdade

Você já usa isto, talvez sem saber o nome.

  • a regra dos trêsSó abstrair na terceira repetição: antes disso, duplicar é mais barato que a abstração errada que um DRY apressado cria.
  • a feature flag que nunca ligouCódigo escrito 'para o futuro' que passou anos desligado é o YAGNI cobrando: não se paga hoje pelo que talvez não venha.
  • o MVPEntregar a versão mínima que resolve o problema, sem os enfeites que ninguém pediu, é KISS e YAGNI virando estratégia de produto.

O padrão em uma linha

Sem nome de domínio, sem cerimônia. Só a ideia.

// Três freios: não repita, não complique, não antecipe.
// Extraia quando a duplicação doer de verdade.

O que ele cobra

Nenhum salto a mais entre a chamada e o efeito.

  • DRY apressado acopla coisas que só pareciam iguais, e desfazer isso depois é caro
  • YAGNI mal lido vira desculpa para não desenhar nem o mínimo necessário

Não vale se: a duplicação é coincidência e as cópias evoluem por motivos diferentes — unificá-las cria um acoplamento que atrapalha mais do que ajuda.

Onde isto aparece

Continue por aqui