Patrón Bridge — demo visual
¿Qué es Bridge?
estructura Bridge separa una abstracción (lo que el cliente usa) de su implementación (cómo se hace),
para que ambas puedan variar independientemente. En vez de herencia profunda, usamos composición:
Abstraction tiene un Implementor.
Diagrama: Abstraction ↔ Implementor
El cliente usa una Abstraction, que delega en un Implementor (A o B) Abstraction: Remote Implementor: TV idle
Demo (Bridge)
operate()Cambia la Abstraction (Remote / AdvancedRemote) y el Implementor (TV / Radio). Luego ejecuta una operación: la abstracción delega en la implementación.
Salida —
Ejemplo del patrón (Bridge)
códigoAbstraction delega en Implementor para desacoplar dos jerarquías.
// bridge.ts
// Implementor
interface Device {
enable(): void;
disable(): void;
setVolume(v: number): void;
getName(): string;
}
class Tv implements Device {
private on = false;
private volume = 10;
enable() { this.on = true; }
disable() { this.on = false; }
setVolume(v: number) { this.volume = Math.max(0, Math.min(100, v)); }
getName() { return "TV"; }
}
class Radio implements Device {
private on = false;
private volume = 10;
enable() { this.on = true; }
disable() { this.on = false; }
setVolume(v: number) { this.volume = Math.max(0, Math.min(100, v)); }
getName() { return "Radio"; }
}
// Abstraction
class Remote {
constructor(protected device: Device) {}
operate(): string {
this.device.enable();
this.device.setVolume(20);
return "Remote → " + this.device.getName() + " (vol=20)";
}
}
class AdvancedRemote extends Remote {
operate(): string {
this.device.enable();
this.device.setVolume(50);
return "AdvancedRemote → " + this.device.getName() + " (vol=50)";
}
}
// Client
const r1 = new Remote(new Tv());
console.log(r1.operate());
const r2 = new AdvancedRemote(new Radio());
console.log(r2.operate()); // bridge.js
class Tv {
constructor() { this.on = false; this.volume = 10; }
enable() { this.on = true; }
disable() { this.on = false; }
setVolume(v) { this.volume = Math.max(0, Math.min(100, v)); }
getName() { return "TV"; }
}
class Radio {
constructor() { this.on = false; this.volume = 10; }
enable() { this.on = true; }
disable() { this.on = false; }
setVolume(v) { this.volume = Math.max(0, Math.min(100, v)); }
getName() { return "Radio"; }
}
class Remote {
constructor(device) { this.device = device; }
operate() {
this.device.enable();
this.device.setVolume(20);
return "Remote → " + this.device.getName() + " (vol=20)";
}
}
class AdvancedRemote extends Remote {
operate() {
this.device.enable();
this.device.setVolume(50);
return "AdvancedRemote → " + this.device.getName() + " (vol=50)";
}
}
const r1 = new Remote(new Tv());
console.log(r1.operate());
const r2 = new AdvancedRemote(new Radio());
console.log(r2.operate()); La clave: <code>Remote</code> no hereda de <code>TV</code>/<code>Radio</code>. En su lugar, <code>Remote</code> <b>compone</b> un <code>Device</code>.