Bridge
Desacopla una abstracción de su implementación para que ambas evolucionen por separado.
Contexto
Tienes una jerarquía de formas (círculo, cuadrado) y una de renderers (SVG, Canvas). Si las cruzas con herencia obtienes una explosión combinatoria: SvgCircle, CanvasCircle, SvgSquare…
Problema
- Acoplas dos jerarquías que cambian por motivos distintos.
- Cualquier nueva variante multiplica las clases.
Solución
Separa abstracción (la jerarquía estable) de implementación (la jerarquía intercambiable) y conéctalas por composición.
#Ejemplo en C#
public interface IRenderer { void DrawCircle(double x, double y, double r); }
public class SvgRenderer : IRenderer { public void DrawCircle(double x,double y,double r) {/* svg */} }
public class CanvasRenderer : IRenderer { public void DrawCircle(double x,double y,double r) {/* canvas */} }
public abstract class Shape
{
protected readonly IRenderer Renderer;
protected Shape(IRenderer r) => Renderer = r;
public abstract void Draw();
}
public class Circle : Shape
{
private readonly double _x, _y, _r;
public Circle(IRenderer r, double x, double y, double radius) : base(r)
=> (_x, _y, _r) = (x, y, radius);
public override void Draw() => Renderer.DrawCircle(_x, _y, _r);
}Cuándo NO aplicarlo
Cuando solo tienes una implementación o no esperas variantes nuevas.
Tradeoffs
| Pro | Contra |
|---|---|
| Evita explosión combinatoria | Mayor complejidad inicial |
| Permite cambiar implementación en runtime | Más indirección |
#structural #gof