Complexidade precisa merecer o lugar
Douglas Pereira
Toda abstração é um empréstimo. Você paga juros no onboarding, no debugger mentindo, no módulo "flexível" que precisa de um caso especial.
Essencial vs acidental
Brooks separou complexidade essencial (o problema) e acidental (a máquina). Moseley e Marks empurraram isso em Out of the Tar Pit: estado e fluxo de controle são onde a complexidade acidental se esconde. Mais camada muitas vezes adiciona estado, não tira.
O teste complementar do Rich Hickey em Simple Made Easy: simples é não entrelaçado, não "familiar." Uma service mesh que você já conhece ainda pode trançar rede, auth e deploy num blob que você não muda por partes.
Orçamento, não vibe
Eu faço três perguntas antes de pacote ou padrão novo:
- O que a gente apaga se isso estiver errado em 90 dias?
- Quantos arquivos mudam para a próxima feature parecida?
- Um colega novo consegue dar grep no nome e achar a verdade?
Se (1) é "rewrite" e (2) é "meio repo," a abstração estourou o orçamento. Duplicação em dois call sites é mais barata do que um kernel compartilhado com um caller.
// connascence of algorithm: os dois mudam juntos
function priceA(n: number) { return n * 1.1 }
function priceB(n: number) { return n * 1.1 }
Essa duplicação é honesta. Um PricingStrategyFactory para dois SKUs não é.
Complexidade permitida
Cache, fila e isolamento multi-tenant são reais. Eles pagam aluguel quando você nomeia o modo de falha que evitam (thundering herd, dual-write, noisy neighbor) e a métrica que diria para removê-los.
Referências
- Brooks, The Mythical Man-Month — complexidade essencial vs acidental
- Moseley & Marks, Out of the Tar Pit (2006)
- Rich Hickey, Simple Made Easy
- Connascence — Meilir Page-Jones
- Hyrum's Law