¿Qué es el patrón del puente?
El patrón de puente es un patrón de diseño estructural. En otras palabras, su trabajo principal es crear una estructura completa a partir de clases y objetos. Un puente hace esto dividiendo una o más clases en jerarquías separadas: abstracción e implementación . Un cambio en la funcionalidad de una jerarquía no implica un cambio en la otra. Eso está muy bien, pero esta definición es muy amplia y no responde a la pregunta más importante: "¿Qué es el patrón del puente?" Creo que te será más fácil entender su aplicación práctica. Entonces, vamos a crear un escenario clásico para el patrón del puente. Tenemos unaShape
clase abstracta, que representa una figura geométrica genérica:
-
Forma.java
public abstract class Shape { public abstract void draw(); }
Cuando decidamos agregar formas como triángulos y rectángulos, haremos que hereden la
Shape
clase: -
Rectángulo.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Triángulo.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
método dependerá de este color. Para tener diferentes implementaciones del draw()
método, necesitamos crear una clase para cada combinación de forma y color. Si tenemos tres colores, entonces necesitamos seis clases: TriangleBlack
, TriangleGreen
, TriangleRed
, y . Seis clases no es un gran problema. ¡Pero! Si necesitamos agregar una nueva forma o color, entonces el número de clases crece exponencialmente. ¿Cómo salir de esta situación? Almacenar el color en un campo y enumerar todas las opciones usando sentencias condicionales no es la mejor solución. Una buena solución es mover el color a una interfaz separadaRectangleBlack
RectangleGreen
RectangleRed
. Dicho y hecho: vamos a crear una Color
interfaz con tres implementaciones: BlackColor
, GreenColor
y RedColor
:
-
Color.java:
public interface Color { void fillColor(); }
-
BlackColor.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } }
-
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } }
-
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }
Ahora agregamos un
Color
campo a laShape
clase. Obtendremos su valor en el constructor. -
Forma.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
Usaremos la
color
variable enShape
implementaciones. Esto significa que las formas ahora pueden usar la funcionalidad de laColor
interfaz. -
Rectángulo.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color color
campo es un puente que conecta dos jerarquías de clases separadas.
Cómo construir un puente: abstracción e implementación
Veamos un diagrama de clases que representa el patrón de puente:
- La abstracción es la
Shape
clase. - RefinedAbstraction es las clases
Triangle
yRectangle
- Implementador es la
Color
interfaz - ConcreteImplementor es el
BlackColor
,GreenColor
yRedColor
las clases.
Shape
clase es una abstracción: un mecanismo para administrar el relleno de formas con varios colores, que se delega en la Color
interfaz (Implementor). Las clases Triangle
y Rectangle
son clases concretas que utilizan el mecanismo puesto a disposición por la Shape
clase. BlackColor
y GreenColor
son RedColor
implementaciones concretas en la jerarquía de implementación.
Dónde usar el patrón de puente
Una gran ventaja de usar este patrón es que puede realizar cambios en las clases funcionales en una jerarquía sin romper la lógica de la otra. Además, este enfoque ayuda a reducir el acoplamiento entre clases. El requisito principal al usar este patrón es "siga las instrucciones", ¡no ignore ninguna de ellas! Con ese fin, averigüemos las situaciones en las que definitivamente debería usar el patrón de puente:-
Si necesita ampliar el número de entidades en base a combinaciones de dos conceptos (por ejemplo, formas y colores).
-
Si desea dividir una clase grande que no cumple con el principio de responsabilidad única en clases más pequeñas que tienen una funcionalidad limitada.
-
Si es necesario realizar cambios en la lógica de ciertas entidades mientras se ejecuta el programa.
-
Si es necesario ocultar una implementación a los clientes de la clase o biblioteca.
Pros y contras del patrón.
Al igual que otros patrones, un puente tiene ventajas y desventajas. Ventajas del patrón de puente:- Mejora la escalabilidad del código: puede agregar funcionalidad sin temor a romper algo en otra parte del programa.
- Reduce el número de subclases cuando el número de entidades estaría basado en combinaciones de dos conceptos (por ejemplo, formas y colores).
- Hace posible trabajar por separado en dos jerarquías separadas: Abstracción e Implementación. Dos desarrolladores diferentes pueden realizar cambios sin profundizar en los detalles del código del otro.
- Reduce el acoplamiento entre clases: el único lugar donde se acoplan las dos clases es el puente (es decir, el
Color color
campo).
- Según la situación específica y la estructura general de un proyecto, podría afectar negativamente el rendimiento de un programa (por ejemplo, si necesita inicializar más objetos).
- Hace que el código sea menos legible debido a la necesidad de cambiar entre las dos clases.
GO TO FULL VERSION