Bridge
Ponte
Separa abstração de implementação para que as duas variem sem multiplicar classes.
Definição
Desacoplar uma abstração da sua implementação, de modo que as duas possam variar independentemente.
Exemplo e motivação
Controle remoto e aparelho
Existem vários tipos de controle remoto (básico, com voz, app no celular) e vários aparelhos (TV, rádio, ar-condicionado). Se cada combinação virasse uma classe, seriam 3 × 3 = 9 classes — e 4 × 4 = 16 quando você adicionasse mais um de cada. A ponte é o protocolo: todo controle fala “ligar / desligar / volume”, e cada aparelho implementa isso do seu jeito. Agora são 3 + 3 classes, e crescem somando, não multiplicando.
Duas dimensões de variação independentes na mesma hierarquia geram explosão combinatória. Forma × Cor: CírculoVermelho, CírculoAzul, QuadradoVermelho, QuadradoAzul… Cada nova cor multiplica o número de classes.
Extraia uma das dimensões para uma hierarquia separada (a Implementação) e faça a hierarquia original (a Abstração) referenciá-la por composição. A “ponte” é essa referência.
- Nomes de classe com duas dimensões coladas:
RelatorioPDFMensal,RelatorioExcelMensal… - Um
if (plataforma)dentro de cada método de uma hierarquia.
- JDBC: a API é a abstração, os drivers são as implementações
- Device drivers de sistema operacional
- React Native / Flutter: mesma API de widget, renderizadores por plataforma
Diagrama
- Abstraction
- Interface de alto nível; mantém uma referência a Implementor e delega o trabalho real.
- RefinedAbstraction
- Variantes da lógica de alto nível.
- Implementor
- Interface das operações primitivas de baixo nível.
- ConcreteImplementor
- Implementações específicas de plataforma/tecnologia.
Aplicabilidade
- Você percebe uma explosão combinatória de subclasses (A × B).
- Você quer estender uma classe em dimensões ortogonais e independentes.
- Você precisa trocar a implementação em tempo de execução.
- Só existe uma implementação e nenhuma previsão de outra.
Consequências
- Cria classes e apps independentes de plataforma.
- O cliente enxerga só a abstração de alto nível.
- Abstração e implementação evoluem separadamente (Aberto/Fechado).
- Troca a implementação em tempo de execução.
- Complica o código quando a classe é coesa e não tem duas dimensões de variação reais.
Código
// ── Implementação: COMO a mensagem sai (o canal) ──────
class Canal { enviar(destino, texto) { throw new Error('abstrato'); } }
class CanalEmail extends Canal { enviar(d, t) { return `✉️ e-mail → ${d}: ${t}`; } }
class CanalSMS extends Canal { enviar(d, t) { return `📱 sms → ${d}: ${t.slice(0, 140)}`; } }
class CanalSlack extends Canal { enviar(d, t) { return `💬 slack → #${d}: ${t}`; } }
// ── Abstração: O QUE é notificado (a política) ────────
class Notificacao {
constructor(canal) { this.canal = canal; } // ← 🌉 A PONTE
enviar(destino, texto) { return this.canal.enviar(destino, texto); }
}
class NotificacaoUrgente extends Notificacao {
enviar(destino, texto) {
// Refina o comportamento SEM saber qual canal está do outro lado.
return this.canal.enviar(destino, `🚨 URGENTE: ${texto.toUpperCase()}`);
}
}
class NotificacaoAgrupada extends Notificacao {
constructor(canal) { super(canal); this.fila = []; }
enviar(destino, texto) { this.fila.push(texto); return null; }
descarregar(destino) {
const resumo = `${this.fila.length} avisos:\n• ` + this.fila.join('\n• ');
this.fila = [];
return this.canal.enviar(destino, resumo);
}
}
// 3 canais × 3 políticas = 9 comportamentos com apenas 6 classes.
console.log(new NotificacaoUrgente(new CanalSMS()).enviar('+5511999', 'servidor caiu'));
console.log(new NotificacaoUrgente(new CanalSlack()).enviar('ops', 'servidor caiu'));
const diario = new NotificacaoAgrupada(new CanalEmail());
diario.enviar('ana@x.com', 'backup ok');
diario.enviar('ana@x.com', 'deploy ok');
console.log(diario.descarregar('ana@x.com')); Relações
- Abstract Factory
- A fábrica pode montar a combinação abstração + implementação correta.
Verificação
Bridge e Strategy têm praticamente o mesmo diagrama. O que realmente as separa?
- A intenção: Bridge separa duas dimensões estruturais que variam; Strategy intercambia algoritmos para uma mesma tarefa
- Bridge usa herança e Strategy usa composição
- Strategy só funciona com métodos estáticos
- Bridge exige no mínimo três implementações concretas
Este é um exemplo clássico de que padrões se distinguem por INTENÇÃO, não por diagrama. A estrutura é a mesma; o problema que resolvem é diferente.