Simplicidade vs. Flexibilidade
Visão Geral
O par parece opor duas virtudes. Não opõe — ele opõe certeza presente a opcionalidade futura.
Flexibilidade é uma opção comprada hoje para ser exercida amanhã. Como qualquer opção, ela tem prêmio: código extra, indireção, conceitos a mais, mais caminhos para testar. E como qualquer opção, ela só se paga se for exercida.
eixo real probabilidade de a mudança acontecer × custo de acomodá-la depois
contra o custo de carregar a opção até lá
A intuição comum erra sistematicamente em uma direção: ela superestima a probabilidade de mudanças específicas e subestima o custo de carregar a opção.
Problema
O ponto de partida é sempre uma pergunta razoável: "e se um dia precisarmos de outro provedor de pagamento?"
A resposta produz uma abstração, uma interface, uma fábrica, uma configuração.
ano 1 um provedor, uma interface, uma implementação, uma configuração
ano 3 um provedor, uma interface, uma implementação, uma configuração
ano 5 troca de provedor — e a interface não serve, porque foi desenhada
a partir do único provedor que existia
O terceiro ano é o resultado mais comum: a opção foi comprada, carregada por anos e nunca exercida. O quinto é o segundo mais comum: a opção foi exercida e não serviu, porque flexibilidade construída sem conhecer o segundo caso acomoda apenas variações do primeiro.
E o oposto também falha. Um sistema construído com zero opcionalidade em pontos que comprovadamente mudam — formatos de dado, regras de negócio voláteis, integrações com parceiros — paga em cada mudança um custo que uma costura mínima teria evitado.
Conceitos Centrais
O eixo real
não é "simples é bom, flexível é bom, escolha"
é a opção vale o prêmio, dada a probabilidade e o custo de adaptar depois?
Três variáveis decidem:
p probabilidade de a mudança acontecer no horizonte relevante
Cd custo de acomodar a mudança depois, sem preparação
Ca custo de carregar a flexibilidade até lá
Compra-se a opção quando p × Cd > Ca. O problema é que p é sistematicamente
superestimado e Ca é subestimado, porque o prêmio é pago em parcelas pequenas — um pouco
de indireção por vez.
Flexibilidade não exercida é custo puro
código a ler quem chega precisa entender a indireção
caminhos a testar cada ponto de variação multiplica cenários
conceitos a explicar a abstração precisa ser ensinada
mudanças mais caras alterar algo genérico é mais difícil que alterar algo específico
O último é o mais contraintuitivo. Uma abstração criada para facilitar mudanças futuras frequentemente dificulta mudanças não previstas, porque ela fixa o eixo ao longo do qual a variação é permitida.
Ver complexidade.
A flexibilidade certa vem dos casos, não da antecipação
um caso conhecido a abstração é adivinhação
dois casos a variação é uma hipótese
três casos o eixo real fica visível
Esta é a razão prática da regra de três: a estrutura que acomoda variação é derivável dos casos, não antecipável a partir de um.
Construir a partir de um caso produz uma abstração com a forma daquele caso — que é exatamente o que não serve quando o segundo aparece. E parar no segundo troca a adivinhação por uma hipótese com uma amostra: a variação que os dois exibem pode ser a que importa, ou pode ser a única que eles têm em comum.
Ver acoplamento contra duplicação.
Custo de adaptar depois nem sempre é alto
O argumento a favor de comprar a opção pressupõe que adaptar depois é caro. Frequentemente não é:
barato de adaptar lógica interna, estrutura de código, escolha de biblioteca
caro de adaptar formato de dado publicado, contrato com externos,
esquema com histórico grande, fronteira de serviço
Para a primeira linha, a resposta é quase sempre construir simples e adaptar quando precisar. Para a segunda, a opcionalidade se paga mesmo com probabilidade baixa.
Isso reformula a pergunta: não é "isto vai mudar?", é "se mudar, quanto custa?"
Sinais de que se comprou flexibilidade demais
pontos de extensão com uma única implementação, há mais de um ano
configuração que nunca foi alterada em nenhum ambiente
interfaces com um implementador
camadas que apenas repassam chamadas
"para o caso de precisarmos" como justificativa em revisão
tempo de integração de pessoas novas dominado por entender a indireção
Três ou mais desses sinais indicam que a opção foi comprada e não será exercida.
Sinais de que se comprou de menos
a mesma mudança exige tocar o mesmo conjunto de arquivos toda vez
copiar-e-adaptar como padrão para variações previsíveis
mudanças de regra de negócio exigindo implantação de código
integrações novas custando o mesmo que a primeira custou
O último é o mais mensurável: se a quinta integração com parceiro custa o mesmo que a primeira, faltou estrutura.
Custo de mudar de ideia é assimétrico
simples → flexível refatoração local, com os casos reais em mãos
flexível → simples remover abstração usada por muitos, com medo de quebrar
A assimetria favorece começar simples. Adicionar flexibilidade depois é feito com informação — os casos existem. Remover flexibilidade é feito com incerteza, porque ninguém sabe quem depende dela.
Este é o argumento decisivo nos empates, e é o item que a intuição mais ignora.
Modelo Mental
Flexibilidade é opção com prêmio pago em parcelas. Compre onde adaptar depois é caro; em todo o resto, espere o segundo caso.
Quando Usar
Prefira flexibilidade quando:
- A mudança é conhecida e datada, não hipotética.
- Adaptar depois exigiria migração de dados ou coordenação entre times.
- O ponto é uma fronteira publicada — formato, contrato, esquema.
- Já existem dois ou mais casos reais.
- O custo da opção é pequeno e localizado.
Prefira simplicidade quando:
- A mudança é hipotética.
- Adaptar depois é refatoração local.
- Existe um único caso conhecido.
- O time é pequeno ou está aprendendo o domínio.
Quando Não Usar
Como dilema, quando é falso. Muitos pontos aceitam uma costura mínima — uma função, uma fronteira nomeada — que custa quase nada e não é abstração.
Sem estimar o custo de adaptar depois — sem esse número, a discussão vira preferência.
Como argumento genérico — "seja flexível" e "seja simples" não decidem nada aplicados ao sistema inteiro. A decisão é ponto a ponto.
Para justificar não decidir — flexibilidade às vezes é adiamento disfarçado de desenho.
Alternativas
- Costura mínima — nomear a fronteira sem criar abstração; barata e reversível.
- Adiar com registro — construir simples e registrar em ADR o que faria a decisão mudar.
- Isolar em vez de generalizar — concentrar o específico num lugar é mais barato que torná-lo genérico.
- Regra de três — esperar o terceiro caso antes de abstrair.
A primeira é a resposta certa com mais frequência do que qualquer dos dois extremos: uma
função cobrarPagamento chamada de um lugar já dá o ponto de costura para o dia em que
houver dois provedores, sem interface nem fábrica.
Trade-offs
| Simplicidade | Flexibilidade |
|---|---|
| Barata de ler e mudar | Acomoda o previsto |
| Adaptação sob demanda | Adaptação já paga |
| Risco: mudança cara | Risco: opção não exercida |
| Reversível | Difícil de remover |
| Comprar a opção cedo | Esperar o segundo caso |
|---|---|
| Pronto quando precisar | Desenho informado por casos reais |
| Forma adivinhada | Espera custa uma mudança |
| Prêmio pago desde já | Prêmio evitado |
Modos de Falha
Opção nunca exercida. Prêmio pago por anos, sem retorno.
Opção que não serve. Construída a partir de um caso, não acomoda o segundo.
Abstração que fixa o eixo errado. Dificulta a mudança que de fato veio.
Simplicidade em fronteira publicada. Adaptar depois exige coordenar externos.
Flexibilidade como adiamento. A decisão difícil é empurrada.
Erros Comuns
Perguntar "isto vai mudar?" em vez de "se mudar, quanto custa?".
Abstrair a partir de um caso.
Não contar o custo de integração de pessoas novas como parte do prêmio.
Não olhar pontos de extensão com um único implementador.
Tratar como decisão global e não ponto a ponto.
Exemplo Real
Uma empresa de pagamentos construiu, em 2021, uma camada de abstração de provedores. A motivação era concreta: a diretoria queria não depender de um único adquirente.
O desenho tinha interface de provedor, fábrica, configuração por ambiente e três pontos de extensão. Custo inicial: cerca de seis semanas.
Em 2024, um segundo adquirente foi contratado. A integração levou quatro meses.
A análise da equipe apontou o motivo:
a interface modelava o fluxo do primeiro adquirente
o segundo tinha autorização em duas etapas, não uma
o modelo de erro era incompatível
a captura era assíncrona, não síncrona
conciliação usava um identificador que a interface não expunha
A abstração acomodava variações do primeiro provedor. O segundo não era uma variação — era outro fluxo.
E havia um custo carregado por três anos que ninguém tinha somado:
arquivos a mais na camada 31
tempo médio de integração de pessoa nova
na área de pagamentos +3 dias, estimado
mudanças que precisaram tocar a abstração
sem mudar de provedor 19
A reconstrução, feita com dois provedores em mãos, levou sete semanas — e produziu uma abstração diferente, em que a autorização em etapas e a captura assíncrona são o modelo base, e o provedor síncrono é o caso simplificado.
O que a equipe passou a fazer:
Costura sem abstração como padrão. Um módulo com funções nomeadas por intenção, chamado de um lugar, sem interface. Quando o segundo caso aparece, a abstração é derivada dos dois.
Custo de adaptar depois estimado antes de comprar opcionalidade, e registrado no ADR. Nos 14 casos avaliados nos dois anos seguintes, 11 tiveram estimativa abaixo de duas semanas — e nenhum desses ganhou abstração antecipada.
Auditoria anual de pontos de extensão. Interfaces com um único implementador há mais de 18 meses são candidatas a remoção. Na primeira rodada, 9 de 23 foram removidas.
Exceção declarada para fronteiras publicadas. Formatos de evento e contratos com externos continuam recebendo versionamento e opcionalidade desde o início, mesmo sem segundo caso — porque adaptar depois exige coordenar terceiros.
A lição registrada: a decisão de 2021 não foi irracional. O erro foi de método — desenhar a variação a partir de um único exemplo. A pergunta que faltou não era "vamos precisar de outro provedor?", que estava certa, e sim "o que sabemos sobre como o segundo provedor será diferente?", cuja resposta honesta era "nada".
Conceitos Relacionados
- Complexidade — o que a flexibilidade acrescenta.
- YAGNI — o princípio correspondente.
- Abstração vs. Complexidade.
- Acoplamento vs. Duplicação — a regra de três.
Exercício Prático
Liste os pontos de extensão do seu sistema — interfaces, configurações, fábricas — e conte quantos têm mais de uma implementação em uso.
Os que tiverem uma só, há mais de um ano, são opções compradas e não exercidas. Some o custo delas.
Perguntas de Entrevista
- Por que "isto vai mudar?" é a pergunta errada?
- Por que uma abstração construída a partir de um caso costuma não servir ao segundo?
- Por que a assimetria do custo de mudar de ideia favorece começar simples?
Para Aprofundar
- Ousterhout, John. A Philosophy of Software Design. 2ª ed. Yaknyam Press, 2021.
- Fowler, Martin. Yagni. martinfowler.com, 2015.
- Brooks, Frederick. No Silver Bullet. IEEE Computer, 1987.