Pular para o conteúdo principal

YAGNI

Visão Geral

YAGNI — You Aren't Gonna Need It — orienta a não construir funcionalidade nem generalização para requisitos que ainda não existem.

A formulação de Martin Fowler é precisa: aplique YAGNI a capacidades presumidas, não a capacidades conhecidas com prazo.

Problema

Construir para o futuro parece prudência e frequentemente é desperdício com boa reputação.

O argumento é sempre o mesmo: "vai ser mais barato fazer agora do que depois". Isso presume duas coisas que raramente se confirmam — que o requisito vai chegar, e que vai chegar na forma prevista.

Mas o custo do desperdício não é o principal. Fowler identifica quatro custos, e os três últimos são os que doem:

Custo de construção — o esforço gasto no que não é usado.

Custo de atraso — o que deixou de ser feito enquanto isso.

Custo de carregar — o código especulativo precisa ser entendido, mantido, migrado e testado por todo o tempo em que existir, por todo mundo que passar por ali. Ele aparece nas buscas, nas revisões e nas migrações de versão.

Custo de reparo — quando o requisito real chega diferente do previsto, é preciso desfazer a generalização antes de fazer o certo. E desfazer é mais caro que ter partido do zero, porque outras coisas já dependem dela.

O quarto é o que inverte a conta. A generalização errada não é neutra; ela é negativa.

Conceitos Centrais

Presumido versus conhecido

SituaçãoAplicar YAGNI?
"Talvez precisemos suportar outro provedor"Sim — presumido
"Contrato assinado exige multi-tenant em julho"Não — conhecido, com prazo
"Um dia vamos internacionalizar"Sim
"Vamos entrar no mercado europeu em Q3, com GDPR"Não
"Isso pode precisar escalar"Sim
"O SLO contratado é 99,9%"Não — é requisito

A distinção é o prazo e o compromisso. Sem os dois, é presunção.

YAGNI não é desculpa para código ruim

Não construir o que não é necessário é diferente de construir mal o que é.

YAGNI diz para não adicionar a interface de plugin que ninguém pediu. Não diz para escrever a funcionalidade atual sem nomes claros, sem testes ou com acoplamento desnecessário.

A confusão entre as duas coisas é usada para justificar pressa, o que inverte o princípio: YAGNI existe para preservar capacidade de mudar, e código ruim a destrói.

O antídoto é reversibilidade

YAGNI funciona porque adicionar depois costuma ser barato — se o código for fácil de mudar.

Isso significa que os dois princípios andam juntos: quanto mais fácil de mudar é o sistema, mais agressivamente YAGNI pode ser aplicado. Num sistema rígido, antecipar tem mais justificativa — o que é um sinal de que o problema real é a rigidez.

Modelo Mental

Pergunte a data. "Quando exatamente vamos precisar disso, e quem se comprometeu com isso?" Sem resposta, é presumido.

Quando Usar

  • Diante de qualquer construção justificada por "vamos precisar".
  • Ao ver parâmetros de configuração sem chamador que os use de forma diferente.
  • Ao ver interface com uma implementação criada "para poder trocar".
  • Em produto em fase de descoberta, quando a maior parte do que se constrói será descartado.

Quando Não Usar

Quando o requisito é conhecido, com prazo e compromisso. Aí não é presunção.

Quando adicionar depois é comprovadamente caro. Alguns casos têm assimetria real: modelo de dados, contrato público de API, identificador de entidade, particionamento. Adicionar multi-tenancy a um esquema com três anos de dados não é o mesmo que adicionar um endpoint.

Quando a escolha é entre duas opções de custo igual. Se a versão mais geral não custa mais, YAGNI não se aplica — não há economia a fazer.

Em decisões de alto custo de reversão. Ver o que é arquitetura. YAGNI é mais seguro quanto mais barato for mudar de ideia.

Quando a "generalização" é higiene básica. Tratar erro, validar entrada e registrar log não são requisitos futuros.

Alternativas

  • Adiar com opção registrada — não construir, mas registrar a condição que levaria a construir. Preserva a análise sem pagar o código.
  • Construir a versão específica bem — de forma que generalizar depois seja barato.
  • Feature flag — construir e não expor, quando o requisito é conhecido mas o momento não.

Trade-offs

Aplicar YAGNIAntecipar
Menos código para manterRequisito futuro já atendido
Menos partes a entenderSem retrabalho se a previsão acertar
Mudança futura custa algoCusto pago agora, mesmo sem uso
Risco de assimetria realRisco de prever errado, e pagar reparo

Modos de Falha

Generalização especulativa. Abstração para variação que não ocorreu, e que precisa ser desmontada quando a variação real chega diferente.

Configuração órfã. Parâmetros que todo chamador passa com o mesmo valor.

YAGNI aplicado a fundação. Modelo de dados sem multi-tenancy num produto que vendia multi-tenancy. O caso em que YAGNI é a decisão errada.

YAGNI como desculpa. Código sem teste e sem nome claro justificado como simplicidade.

Erros Comuns

Aplicar a requisito conhecido com prazo. Ver a tabela acima.

Aplicar a decisões de alto custo de reversão. Onde a assimetria é real, antecipar é prudência.

Ignorar o custo de carregar. Quem defende antecipação normalmente só compara custo de construir agora com custo de construir depois, e ignora os anos de manutenção do código não usado.

Confundir com "não pense no futuro". YAGNI é sobre não construir. Pensar, registrar a condição e projetar para reversibilidade é o oposto de imprudência.

Exemplo Real

Um time construiu um sistema de notificações com abstração para "qualquer canal": e-mail, SMS, push, webhook, com registro dinâmico de canais e roteamento configurável.

Requisito real na época: enviar e-mail.

Três anos depois, o sistema enviava e-mail e push. Dois canais, não cinco. E a abstração não serviu para o push: ela modelava mensagem como texto com assunto, e push precisava de payload estruturado com ação. O canal de push foi adicionado contornando a abstração.

Contabilizando: dois meses de construção inicial, três anos de manutenção de um mecanismo de roteamento que nunca roteou nada, e um contorno permanente que qualquer pessoa que lê o código precisa entender.

O contraste no mesmo sistema: o identificador de destinatário foi definido como opaco desde o início, em vez de "endereço de e-mail". Isso foi antecipação — e foi correta, porque mudar o tipo de um identificador depois de três anos de dados é caro de forma assimétrica.

A diferença entre os dois casos não é ter previsto o futuro. É que um era barato de adicionar depois e o outro não.

Conceitos Relacionados

  • KISS — o mesmo espírito aplicado a estrutura.
  • Abstração — o custo da generalização prematura.
  • Complexidade — o que a especulação adiciona.

Exercício Prático

Encontre no seu sistema três pontos de extensão — interface, configuração, mecanismo de plugin.

Para cada um: quantas implementações ou valores distintos existem hoje? Se for um, quando ele foi criado e qual requisito futuro o justificava? Esse requisito chegou?

Perguntas de Entrevista

  • Quais são os custos de construir para um requisito que não chegou?
  • Quando antecipar é a decisão correta?
  • Como YAGNI se relaciona com decisões de alto custo de reversão?

Para Aprofundar

  • Fowler, Martin. Yagni, 2015 — os quatro custos.
  • Beck, Kent. Extreme Programming Explained. 2ª ed., 2004.
  • Fowler, Martin. Refactoring. 2ª ed., 2018 — o code smell de generalidade especulativa.