Decorator: somando comportamentos sem herança
Cache, log e compressão opcionais sem explosão de subclasses: o Decorator com código real, os lugares onde você já o usa (middlewares!) e quando é só cerimônia.
Todo sistema tem aquele requisito que chega em camadas: "o relatório agora precisa de cache". Depois: "e de log de acesso". Depois: "e de compressão, mas só para clientes premium". A solução ingênua é herança (RelatorioComCacheELogECompressao), e ela explode combinatoriamente: 3 comportamentos opcionais = 8 subclasses possíveis. O Decorator resolve exatamente isso: embrulhar um objeto com comportamentos adicionais, um de cada vez, em tempo de execução.
O padrão em código real
A chave: o decorador implementa a mesma interface do que embrulha, e delega o trabalho real para dentro:
interface FonteDeDados {
buscar(consulta: string): Promise<Resultado>;
}
// O trabalho real
class ApiDeVendas implements FonteDeDados {
async buscar(consulta: string) {
return this.http.get(`/vendas?q=${consulta}`);
}
}
// Decorador 1: cache
class ComCache implements FonteDeDados {
constructor(private interna: FonteDeDados, private cache: Cache) {}
async buscar(consulta: string) {
const salvo = await this.cache.get(consulta);
if (salvo) return salvo;
const resultado = await this.interna.buscar(consulta); // delega
await this.cache.set(consulta, resultado, 300);
return resultado;
}
}
// Decorador 2: métricas
class ComMetricas implements FonteDeDados {
constructor(private interna: FonteDeDados, private metrics: Metrics) {}
async buscar(consulta: string) {
const inicio = Date.now();
try {
return await this.interna.buscar(consulta);
} finally {
this.metrics.tempo("busca_vendas", Date.now() - inicio);
}
}
}
// A composição: escolha as camadas por configuração
const fonte = new ComMetricas(new ComCache(new ApiDeVendas(), redis), metrics);
Quem consome fonte não sabe (nem precisa saber) quantas camadas existem: a interface é a mesma. Precisou de mais um comportamento? Mais um embrulho, sem tocar nas classes existentes: é o princípio aberto/fechado em forma prática, e cada camada é testável isolada, com um dublê no lugar da interna.
Você já usa isso todo dia (só não chama assim)
O Decorator é dos padrões mais presentes no cotidiano moderno, de outros nomes:
- Middlewares (Express, API Gateway, interceptors do Angular/Axios): cada um embrulha o handler seguinte com auth, log, retry. É uma cadeia de decoradores com outra roupa.
- Streams do Node: o gzip embrulhando a leitura do arquivo.
- Wrappers de resiliência: retry, timeout e circuit breaker em volta de chamadas externas são decoradores canônicos: a política fica em camadas reutilizáveis, fora da lógica de negócio.
E o cuidado com o falso amigo: os @decorators do TypeScript/Python compartilham o nome e o espírito (embrulhar), mas são um recurso de linguagem aplicado na declaração; o padrão GoF composta objetos em runtime, por configuração. Parentes, não gêmeos.

Quando usar (e quando é cerimônia)
Use quando: comportamentos são opcionais e combináveis (cache sim/não × log sim/não × compressão por plano), transversais à lógica (o cache não é assunto da API de vendas), e você quer ligar/desligar por configuração ou por cliente.
Não use quando: o comportamento é obrigatório e único (coloque na própria classe), ou a "pilha" tem uma camada só e nunca terá outra: aí é indireção sem retorno. E o cheiro de abuso: decorador que muda a semântica (retorna outra coisa, engole erros silenciosamente) quebra o contrato que o padrão promete manter, virando armadilha de depuração.
A régua da série continua: padrão resolve problema, não decora currículo. Três camadas bem nomeadas valem ouro; sete camadas para um CRUD são complexidade comprada sem necessidade.
No próximo artigo, o primo que todo mundo confunde com este: o Proxy, mesmo desenho, intenção diferente. Padrões aplicados com esse critério são parte do olhar de revisão do nosso serviço de Arquitetura de Software.
Tem uma classe com sufixo ComCacheELog no seu código? Cole a assinatura para a IA da Rabelo Digital, aqui no canto da tela, e ela desenha a pilha de decoradores equivalente. Sem formulário, sem espera.


Deixe um Comentário