Cadeia de Responsabilidade: Código Limpo para Lógica de Negócios Desenfreada

Cadeia de Responsabilidade: Código Limpo para Lógica de Negócios Desenfreada

Cadeia de Responsabilidade: Código Limpo para Lógica de Negócios Desenfreada

Deixe-me contar sobre aquela função que apavorava meus sonhos.

Todo sistema, em algum momento, acaba com uma função que ninguém quer mexer. Ela começa pequena: uma verificação de validação, um `if` aqui, outro ali. Depois vão acumulando requisitos, os stakeholders pedem "só uma pequena exceção", e de repente você está olhando para um monstro de 500 linhas que parece escrito por comitê (porque foi).

É aí que a Cadeia de Responsabilidade salva o dia — não com mágica, mas com disciplina. Deixa eu explicar como esse padrão clássico de design pode desembaraçar sua lógica de negócios mais enrolada.

O Que é Cadeia de Responsabilidade?

No fundo, Cadeia de Responsabilidade é sobre passar uma requisição ao longo de uma sequência de manipuladores até que um deles a processe. Pense nisso como uma fila de escalonamento no atendimento ao cliente — cada pessoa tenta resolver seu problema, e se não consegue, passa para a próxima na linha.

Em termos de código, em vez de ter um método gigante lidando com todos os cenários possíveis, você cria uma série de manipuladores menores e focados. Cada manipulador processa a requisição ou passa para o próximo da cadeia.

Cenários Reais Onde a Cadeia Brilha

Processamento de Pedidos em E-commerce

Imagine só: você está construindo uma plataforma de comércio eletrônico, e sua função `processOrder()` precisa lidar com códigos de desconto, pontos de fidelidade, promoções sazonais, contas corporativas, status VIP e parcerias especiais. Sua função explode para centenas de linhas com condicionais aninhados.

Com Cadeia de Responsabilidade, você cria processadores individuais:

```javascript
class DiscountCodeHandler {
handle(order) {
// Aplica lógica de desconto
return next ? next.handle(order) : order;
}
}

class LoyaltyPointsHandler {
handle(order) {
// Aplica pontos de fidelidade
return next ? next.handle(order) : order;
}
}
```

Cada manipulador foca em uma coisa só, facilitando testes e manutenção.

Pipeline de Moderação de Conteúdo

Plataformas de redes sociais enfrentam fluxos de moderação complexos. Uma postagem pode precisar ser checada contra diretrizes da comunidade, analisada quanto a discurso de ódio, sinalizada por conteúdo político, revisada por violações de direitos autorais e avaliada quanto a desinformação — tudo antes da publicação.

Ao invés de tudo em uma única função de moderação, você constrói um pipeline:

1. **Manipulador de Detecção de Spam** – Filtra spams óbvios
2. **Manipulador de Discurso de Ódio** – Sinaliza linguagem abusiva
3. **Manipulador de Direitos Autorais** – Verifica material protegido
4. **Manipulador de Conteúdo Político** – Direciona postagens políticas sensíveis
5. **Manipulador de Revisão Final** – Revisão por moderador humano

Cada etapa processa o conteúdo de forma adequada ou passa adiante.

Fluxo de Autorização de Pagamento

Processamento de pagamentos envolve múltiplas camadas de validação e aprovação. Em vez de um processador único, considere essa sequência:

1. **Manipulador de Detecção de Fraude** – Bloqueia transações suspeitas
2. **Manipulador de Limite de Crédito** – Garante fundos suficientes
3. **Manipulador de Verificação Bancária** – Confirma validade da conta
4. **Manipulador de Conversão de Moeda** – Trata pagamentos internacionais
5. **Manipulador de Gateway de Pagamento** – Processa a transação real

Essa abordagem facilita adicionar novas etapas de verificação sem mexer no código existente.

Implementando Sua Primeira Cadeia

Aqui está uma implementação prática em JavaScript:

```javascript
// Classe base de manipulador
class BaseHandler {
constructor() {
this.nextHandler = null;
}

setNext(handler) {
this.nextHandler = handler;
return handler;
}

handle(request) {
if (this.nextHandler) {
return this.nextHandler.handle(request);
}
return null; // Nenhum manipulador processou a requisição
}
}

// Manipuladores concretos
class AuthenticationHandler extends BaseHandler {
handle(request) {
if (!request.user) {
return { error: 'Autenticação necessária' };
}
console.log('Autenticação aprovada');
return super.handle(request);
}
}

class AuthorizationHandler extends BaseHandler {
handle(request) {
if (request.user.role !== 'admin') {
return { error: 'Permissões insuficientes' };
}
console.log('Autorização aprovada');
return super.handle(request);
}
}

class ValidationHandler extends BaseHandler {
handle(request) {
if (!request.data || Object.keys(request.data).length === 0) {
return { error: 'Dados inválidos' };
}
console.log('Validação aprovada');
return super.handle(request);
}
}

// Uso
const authHandler = new AuthenticationHandler();
const authzHandler = new AuthorizationHandler();
const validationHandler = new ValidationHandler();

authHandler.setNext(authzHandler).setNext(validationHandler);

const resultado = authHandler.handle({
user: { role: 'admin' },
data: { amount: 100 }
});
```

Benefícios que Realmente Importam

**Manutenibilidade**: Cada manipulador faz uma coisa e faz bem. Quando as regras de negócio mudam, você modifica apenas o manipulador relevante.

**Testabilidade**: Testes unitários ficam diretos — você testa cada manipulador isoladamente em vez de simular cenários complexos.

**Flexibilidade**: Precisa reordenar etapas de processamento? Muda a configuração da cadeia. Quer adicionar rotas condicionais? Implementa lógica personalizada nos manipuladores.

**Depuração**: Quando algo dá errado, você sabe exatamente qual manipulador falhou, porque cada um registra sua decisão.

Armadilhas Comuns a Evitar

Não caia na tentação de tornar manipuladores muito genéricos ou muito específicos. Encontre um equilíbrio onde cada manipulador represente uma regra de negócio significativa. Também resiste a tentação de fazer manipuladores cientes de sua posição na cadeia — deixe-os focados em sua responsabilidade e confie na cadeia para funcionar.

Lembre-se: Cadeia de Responsabilidade não substitui toda sua lógica condicional. É sobre organizar fluxos complexos onde múltiplas etapas precisam acontecer em sequência.

Ferramentas e Frameworks que Acreditam na Cadeia

Muitos frameworks modernos já implementam variações desse padrão:

- **Middleware do Express.js** ([expressjs.com](https://expressjs.com)) usa uma abordagem semelhante à cadeia
- **Pipeline de middleware do ASP.NET Core** segue princípios similares
- **Filtros Java Servlet** implementam processamento em cadeia

Mesmo que seu framework não use Cadeia de Responsabilidade explicitamente, entender esse padrão ajuda a projetar melhor sua arquitetura de middleware e interceptadores.

Quando NÃO Usar Cadeia de Responsabilidade

A cadeia não é uma bala de prata. Evite-a quando:

- Etapas de processamento estão fortemente acopladas e sempre executam juntas
- Performance é crítica e você precisa minimizar chamadas de método
- A ordem de processamento não importa ou é fixa
- Você tem menos de três etapas distintas de processamento

Como Aplicar no Seu Projeto

Pronto para introduzir Cadeia de Responsabilidade no seu projeto? Comece pequeno:

1. Identifique uma função complexa que todo mundo evita tocar
2. Divida em etapas lógicas de processamento
3. Crie classes separadas de manipuladores para cada etapa
4. Conecte-as em uma cadeia
5. Teste bem antes de expandir para outras áreas

O investimento se paga rápido com menos tempo de depuração e revisões de código mais limpas.

FAQ

**P: Como trato erros na cadeia?**
R: Cada manipulador deve processar a requisição com sucesso ou lançar uma exceção apropriada. Considere implementar um manipulador de erros ao final da cadeia para capturar requisições não processadas.

**P: Os manipuladores podem modificar a requisição ao longo do caminho?**
R: Com certeza! Essa é prática comum. Cada manipulador pode enriquecer, validar ou transformar os dados da requisição para os manipuladores subsequentes.

**P: E quanto a processamento assíncrono?**
R: Implementações modernas frequentemente suportam padrões async/await. Apenas garanta que cada manipulador faça await no próximo manipulador da cadeia.

**P: Como isso se compara ao padrão Strategy?**
R: Strategy escolhe um algoritmo entre vários, enquanto Cadeia de Responsabilidade tenta múltiplos manipuladores em sequência até que um processe a requisição.

A beleza da Cadeia de Responsabilidade está em sua simplicidade. Ela não resolve todos os problemas arquiteturais, mas quando aplicada corretamente, transforma código espaguete inmaintável em lógica organizada e legível que seu futuro eu vai agradecer.

Comments (0)

No comments yet. Be the first to comment!

Leave a Comment