# Propósito
El patrón Bridge tiene como objetivo desacoplar una abstracción de su implementación, de manera que ambas puedan variar de forma independiente. Lo vuelve más flexible, cambia la herencia por composición.
# Problema
El problema de tener una estructura rígida, donde la abstracción y su implementación están muy acopladas, lo que limita la flexibilidad y extensión porque cualquier cambio en la implementación puede requerir cambiar la abstracción.
# Solución
-
Separar Abstracciones e Implementaciones: Define dos jerarquías de clases separadas.
-
Puente entre Abstracción e Implementación: Usa composición para conectar las abstracciones con sus implementaciones.
# Estructura
# Participantes
- Abstraction: Define la interfaz de alto nivel y mantiene una referencia a Implementor.
- RefinedAbstraction: Extiende o refina la interfaz de Abstraction.
- Implementor: Define la interfaz para las implementaciones.
- ConcreteImplementor: Implementa la interfaz de Implementor.
# Cuándo Usarlo
-
Evitar un enlace permanente entre abstracción e implementación.
-
Ambas jerarquías deben ser extensibles mediante subclases.
-
Los cambios en la implementación no deben afectar a los clientes.
# Ventajas
-
verified
Separación de intereses: Separa aspectos de alto nivel de detalles de bajo nivel.
-
verified
Extensibilidad: Ambas jerarquías crecen independientemente.
# Desventajas
-
warning
Complejidad: Introduce una capa adicional de abstracción.
-
warning
Rendimiento: Pequeña penalización por la capa de abstracción.
# Ejemplo: Sistema de dibujo
Desarrollamos un software de dibujo que debe ofrecer flexibilidad en cómo se dibujan distintas figuras (pantalla o papel).
Problema
Codificar cada combinación de forma y método de dibujo en clases rígidas dificulta el crecimiento del sistema.
Solución planteada
Usamos un Bridge para separar la abstracción (formas) de la implementación (métodos de dibujo DrawAPI).
# Código Java
interface DrawAPI {
void drawCircle(double x, double y, double radius);
void drawRectangle(double x, double y, double w, double h);
}
class DrawOnScreen implements DrawAPI {
public void drawCircle(double x, double y, double r) { /*...*/ }
public void drawRectangle(double x, double y, double w, double h) { /*...*/ }
}
abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) { this.drawAPI = drawAPI; }
public abstract void draw();
}
class Circle extends Shape {
private double x, y, r;
public Circle(double x, double y, double r, DrawAPI api) { super(api); /*...*/ }
public void draw() { drawAPI.drawCircle(x, y, r); }
}
# Conclusiones
Nuestro software se vuelve más flexible y fácil de mantener al poder extender formas y métodos de dibujo independientemente.
# Patrones relacionados
Abstract Factory
Puede crear y configurar un bridge.
Adapter
Adapter cambia interfaces; Bridge separa interfaz de implementación.