java - pattern - ¿El patrón de puente desacopla una abstracción de la implementación?
design pattern proxy (3)
Esta declaración simplemente significa que puede cambiar de implementador, al que apunta la abstracción, en tiempo de ejecución y todo debería funcionar (como en el Patrón de estrategia; pero en el Patrón de estrategia, solo las estrategias son abstractas). También se puede entender que separa dos clases, de modo que no tienen que conocerse más que sus interfaces.
Aprendí el patrón Bridge de diferentes artículos y lo he implementado según mi entendimiento. Una cosa que me está confundiendo es el patrón de puente, dice.
BridgePattern desacopla una abstracción de su implementación para que los dos puedan variar independientemente
¿Qué significa esta afirmación? ¿La implementación reside en un frasco separado?
¿Cuál es el significado de variar independientemente declaración?
Considerando el artículo de journaldev proporcionado, elabore la respuesta.
Cualquier ayuda es muy apreciada.
Para mí, Bridge no es realmente el DP más importante de la Biblia del GOF, ya que es principalmente un derivado de la Estrategia. Como algunos otros patrones que no han envejecido tan bien (¿método de fábrica?) Implica más herencia con clases abstractas que mantienen el comportamiento que otros patrones, por lo tanto, es menos aplicable en general.
La mayor parte de la estrategia es hacer el gran trabajo, pero un problema importante con la estrategia es que la estrategia a menudo necesita conocimiento sobre su contexto.
En algunos idiomas, esto lleva a que las estrategias se declaren amiga del contexto, o estrategias definidas como clases internas en Java.
Esto significa que el contexto a menudo termina con el conocimiento de la existencia de varias estrategias concretas. Puede evitar esto utilizando una función setStrategy (), pero la dependencia inversa de la estrategia concreta al contexto generalmente sobrevive, debido a razones de eficiencia (usted quiere manipular las estructuras de datos del contexto directamente).
Este problema está resuelto por Bridge, ya que el contexto de la Estrategia ahora es abstracto, pero sigue siendo una clase a priori, ya que tiene al menos el código de Estrategia. Por lo general, debe definir una API de acceso suficiente para que funcionen las Estrategias concretas, posiblemente con agujeros, es decir, métodos abstractos. Pones una aparición de AbstractContext en la firma de las operaciones en AbstractStragey y estás bien.
Así que en mi punto de vista, Bridge completa la estrategia al hacer que el contexto sea lo suficientemente concreto para que funcionen, pero aun así lo suficientemente abstracto como para que pueda ser refinado ortogonalmente con estrategias concretas (con efectos de retroalimentación cuando se implementa el API abstracto del contexto en el que las estrategias concretas en realidad utilizar).
Una forma más sencilla de ver el puente es decir que las operaciones de AbstractStrategy siempre deben tomar las abstracciones como parámetros en lugar de saber realmente íntimamente su contexto.
Para responder con más precisión a la pregunta OP:
¿Qué significa esta afirmación? ¿La implementación reside en un frasco separado?
Sí, de hecho, por lo general, podría definir la abstracción y el implementador en un paquete "base" (podrían ser interfaces). Los implementadores concretos pueden residir en un paquete "implXX". El contexto concreto puede residir en paquetes separados "contXX". No hay ciclos en el gráfico de dependencia, todos dependen de la base, el nuevo "contXX" y "implXX" se pueden definir de forma independiente (no hay ninguna dependencia entre ellos), por lo tanto, la declaración en negrita en el OP.
¿Cuál es el significado de variar independientemente declaración?
Piense en un plugin de editor en eclipse; debe manejar las acciones en los botones y clics (como una estrategia), pero la acción real que debe realizar la estrategia es actuar en el estado del editor en sí (por ejemplo, "texto destacado"). Usted define lo que un editor posee de una manera abstracta, incluido el hecho de que tiene Handler para clics y pulsaciones de teclas, así como funciones de resalte y navegación, incluso estas pueden ser anuladas por editores concretos (flash en lugar de resaltado). Eso es un puente, puede definir nuevos editores y un nuevo controlador de forma independiente.
Con una inyección de dependencia (por ejemplo, una guía de Google) o un código de fábrica manual o una orientación de los componentes para establecer claramente la estrategia desde el exterior, se obtiene un acoplamiento muy bajo de las diversas partes de la aplicación.
Considerando el artículo de journaldev proporcionado, elabore la respuesta.
Honestamente, creo que esta no es la mejor aplicación de la DP, ya que las implementaciones de Color no parecen preocuparse mucho por su contexto. Debe usar un decorador aquí ya que el color es una preocupación independiente de Shape.
Eche un vistazo a estas diapositivas para encontrar una solución con un decorador (en parte en francés, lo siento). https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-9.pdf (diapositivas 16-18) según el ejemplo presentado aquí: https://www-licence.ufr-info-p6.jussieu.fr/lmd/licence/2015/ue/3I002-2016fev/cours/cours-4.pdf diapositivas 10 a 15.
En ese ejemplo, necesitaríamos Bridge si "updateInertie" fuera miembro de Forme, lo que no suena absurdo. Una vez más, el puente emerge más como una combinación de otros patrones.
BridgePattern desacopla una abstracción de su implementación .
La abstracción y la implementación pueden variar independientemente ya que la clase concreta no implementa directamente la abstracción (interfaz)
Nota clave: dos jerarquías de clases ortogonales (la jerarquía de abstracción y la jerarquía de implementación ) están vinculadas mediante la composición (y no la herencia). Esta composición ayuda a ambas jerarquías a variar de forma independiente.
La implementación nunca se refiere a la abstracción. La abstracción contiene la interfaz de implementación como miembro (a través de la composición).
Volviendo a su pregunta sobre el código de ejemplo en el artículo de journaldev :
La forma es abstracción
Triángulo se redefineAbstracción
Color es implementador
RedColor es ConcreteImplementor
Un objeto Shape concreto: el triángulo extiende Shape pero no implementa la interfaz Color .
public class Triangle extends Shape{
}
RedColor y GreenColor realmente implementan la interfaz de Color .
El objeto Forma concreta ( Triángulo ) es independiente de la implementación de la abstracción (es decir, la interfaz de color ).
Shape tri = new Triangle(new RedColor());
Aquí Triángulo contiene un objeto de color concreto ( Composición ). Si hay un cambio en la abstracción de Color (interfaz), RedColor y GreenColor son responsables de implementar la abstracción de la interfaz de Color .
Las formas como Triangle no se ven afectadas por los cambios en el contrato de la interfaz de Color . Así que la interfaz de color puede variar independientemente. Esto es posible porque Shape tiene el contrato que usa Composición en lugar de implementación .
En resumen,
- El puente es un patrón estructural.
- La abstracción y la implementación no están vinculadas en tiempo de compilación
- Abstracción e implementación: ambos pueden variar sin impacto en el cliente
Use el patrón Puente cuando:
- Quieres un enlace en tiempo de ejecución de la implementación,
- Tiene una proliferación de clases desde una interfaz acoplada y numerosas implementaciones,
- Quieres compartir una implementación entre múltiples objetos,
- Necesitas mapear jerarquías de clases ortogonales.
Enlaces útiles:
tutorialspoint artice
articulo dzone
oodesign articulo
artículo de sourcemaking
Publicación relacionada:
¿Cuándo usas el patrón de puente? ¿En qué se diferencia del patrón adaptador?