Ifless
Ifless é uma abordagem de desenvolvimento que busca reduzir ou eliminar estruturas condicionais explícitas, como if, else e switch, substituindo-as por mecanismos declarativos, composição de comportamento, polimorfismo, tabelas de decisão, mapeamentos e estratégias orientadas a dados.
O objetivo é reduzir acoplamento lógico, melhorar extensibilidade e minimizar ramificações de execução dispersas pelo código.
Essa abordagem é comum em arquiteturas orientadas a domínio, motores de regras, sistemas configuráveis e aplicações com grande quantidade de regras condicionais.
Problema das Condicionais Excessivas
Estruturas condicionais são fundamentais em programação, porém seu uso excessivo tende a gerar:
- Alta complexidade ciclomática.
- Crescimento exponencial de cenários.
- Acoplamento entre regras de negócio.
- Dificuldade de extensão.
- Baixa previsibilidade comportamental.
- Duplicação lógica.
Exemplo clássico:
if (tipo.equals("PIX")) {
processarPix();
} else if (tipo.equals("BOLETO")) {
processarBoleto();
} else if (tipo.equals("CARTAO")) {
processarCartao();
}
Com o aumento de regras, o bloco cresce continuamente, violando o princípio Open/Closed.
Estratégias Utilizadas em Ifless
Polimorfismo
Uma das abordagens mais comuns consiste em delegar comportamento para implementações específicas.
Exemplo
public interface Pagamento {
void processar();
}
public class PixPagamento implements Pagamento {
public void processar() {
System.out.println("Processando PIX");
}
}
public class BoletoPagamento implements Pagamento {
public void processar() {
System.out.println("Processando boleto");
}
}
Uso:
pagamento.processar();
A decisão deixa de existir no fluxo principal e passa a ser resolvida pela abstração.
Strategy Pattern
O padrão Strategy encapsula algoritmos intercambiáveis.
Exemplo
Map<String, Runnable> estrategias = Map.of(
"PIX", this::processarPix,
"BOLETO", this::processarBoleto,
"CARTAO", this::processarCartao
);
estrategias.get(tipo).run();
Benefícios:
- Remoção de cadeias condicionais.
- Facilidade de extensão.
- Centralização comportamental.
Tabelas de Decisão
Outra técnica consiste em transformar lógica condicional em dados estruturados.
Exemplo
{
"PIX": {
"taxa": 0,
"assincrono": false
},
"BOLETO": {
"taxa": 3.99,
"assincrono": true
}
}
O sistema passa a interpretar configurações em vez de executar múltiplas decisões imperativas.
Essa abordagem é comum em:
- Motores de regras.
- Feature flags.
- Sistemas tributários.
- Sistemas financeiros.
- Pipelines configuráveis.
Programação Funcional
Paradigmas funcionais favorecem abordagens ifless por meio de:
- Funções puras.
- Pattern matching.
- Composição funcional.
- Funções de alta ordem.
Exemplo em JavaScript
const operacoes = {
soma: (a, b) => a + b,
subtracao: (a, b) => a - b,
};
operacoes[tipo](1, 2);
A seleção ocorre por resolução de estrutura de dados, não por fluxo condicional explícito.
State Pattern
Estados distintos encapsulam comportamentos específicos.
Exemplo
estadoAtual.processarPedido();
Em vez de:
if (status == PAGO) {
...
} else if (status == CANCELADO) {
...
}
Cada estado controla sua própria transição e comportamento.
Engines de Regras
Sistemas altamente condicionais frequentemente utilizam motores especializados.
Exemplos:
- Drools
- OpenL Tablets
- Camunda DMN
Nesses cenários:
- Regras são externalizadas.
- Fluxos tornam-se declarativos.
- Alterações deixam de exigir recompilação.
Vantagens
Extensibilidade
Novos comportamentos podem ser adicionados sem alterar código existente.
Redução de Acoplamento
Regras deixam de depender de grandes blocos centralizados.
Melhor Organização
Cada comportamento possui responsabilidade isolada.
Testabilidade
Fluxos tornam-se mais previsíveis e unitariamente testáveis.
Escalabilidade Cognitiva
Sistemas complexos tornam-se mais navegáveis.
Desvantagens
Excesso de Abstração
Aplicações simples podem tornar-se artificialmente complexas.
Indireção Excessiva
Fluxos podem ficar difíceis de rastrear.
Sobrecarga Arquitetural
Nem toda condicional justifica abstrações adicionais.
Debugging Mais Complexo
Encadeamentos dinâmicos podem dificultar análise de execução.
Quando Utilizar
Ifless tende a ser útil em:
- Sistemas orientados a regras.
- Fluxos extensíveis.
- Plataformas multi-tenant.
- Aplicações configuráveis.
- Processamentos com múltiplas variações comportamentais.
Pode ser contraproducente em:
- Scripts simples.
- Lógicas triviais.
- Fluxos lineares pequenos.
Relação com Clean Code
Ifless possui forte relação com princípios como:
- Open/Closed Principle.
- Single Responsibility Principle.
- Tell, Don’t Ask.
- Composition Over Inheritance.
A proposta não é eliminar completamente condicionais, mas evitar centralização excessiva de decisões.
Conclusão
Ifless é uma abordagem arquitetural voltada à redução de ramificações explícitas por meio de abstrações comportamentais e modelagem declarativa.
Seu principal benefício está na manutenção de sistemas complexos com múltiplas regras de negócio, especialmente quando há necessidade frequente de extensão e customização comportamental.
A adoção indiscriminada, entretanto, pode introduzir abstrações desnecessárias. O uso adequado depende do volume de regras, variabilidade do domínio e necessidade de extensibilidade.