design patterns - pattern - Diferencia entre patrón de puente y patrón de adaptador
proxy pattern (6)
¿Cuál es la diferencia entre los patrones Bridge y Adaptor? Donde puedo usar cada patrón?
"Adapter hace que las cosas funcionen una vez que están diseñadas; Bridge las hace funcionar antes que ellas. [GoF, p219]"
Efectivamente, el patrón de Adaptador es útil cuando tiene un código existente, ya sea de terceros o en la empresa, pero fuera de su control, o de lo contrario no es modificable para cumplir con la interfaz que necesita. Por ejemplo, tenemos un SuperWeaponsArray que puede controlar una gran variedad de dispositivos apocalípticos.
public class SuperWeaponsArray {
/*...*/
public void destroyWorld() {
for (Weapon w : armedWeapons) {
w.fire();
}
}
}
Estupendo. Excepto que nos damos cuenta de que tenemos un dispositivo nuclear en nuestro arsenal que es muy anterior a la conversión a la interfaz de Arma. Pero realmente nos gustaría que funcione aquí ... entonces, ¿qué hacemos ...?
NukeWeaponsAdaptor: basado en nuestra clase Nuke, pero exportando la interfaz de Arma. Dulce, ahora seguramente podemos destruir el mundo. Parece un poco complicado, pero hace que las cosas funcionen.
El patrón Bridge es algo que implementas por adelantado: si sabes que tienes dos jerarquías ortogonales, proporciona una manera de desacoplar la interfaz y la implementación de tal forma que no obtienes una cantidad insana de clases. Digamos que tienes:
MemoryMappedFile y DirectReadFile tipos de objetos de archivo. Digamos que desea poder leer archivos de varias fuentes (implementaciones de Linux frente a Windows, etc.). Bridge te ayuda a evitar terminar con:
MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile
Bridge es un Adaptador mejorado. Bridge incluye adaptador y le agrega flexibilidad adicional. Así es como los elementos del mapa de respuestas de Ravindra entre patrones:
Adapter | Bridge
-----------|---------------
Target | Abstraction
-----------|---------------
| RefinedAbstraction
|
| This element is Bridge specific. If there is a group of
| implementations that share the same logic, the logic can be placed here.
| For example, all cars split into two large groups: manual and auto.
| So, there will be two RefinedAbstraction classes.
-----------|---------------
Adapter | Implementor
-----------|---------------
Adaptee | ConcreteImplementor
Esta publicación ha estado presente por bastante tiempo. Sin embargo, es importante entender que una fachada es similar a un adaptador, pero no es lo mismo. Un adaptador "adapta" una clase existente a una clase de cliente generalmente no compatible. Digamos que tiene un viejo sistema de flujo de trabajo que su aplicación utiliza como cliente. Su empresa posiblemente podría reemplazar el sistema de flujo de trabajo por uno nuevo "incompatible" (en términos de interfaces). En la mayoría de los casos, puede usar el patrón de adaptador y escribir código que realmente llame a las nuevas interfaces del motor de flujo de trabajo. Un puente generalmente se usa de una manera diferente. Si realmente tiene un sistema que necesita trabajar con diferentes sistemas de archivos (es decir, disco local, NFS, etc.) puede usar el patrón de puente y crear una capa de abstracción para trabajar con todos sus sistemas de archivos. Esto sería básicamente un caso de uso simple para el patrón de puente. La fachada y el adaptador comparten algunas propiedades, pero las fachadas se usan generalmente para simplificar una interfaz / clase existente . En los primeros días de EJB no había llamadas locales para EJB. Los desarrolladores siempre obtuvieron el código auxiliar, lo redujeron y lo llamaron "pseudo-remotamente". Esto muchas veces causaba problemas de rendimiento (especialmente cuando se llamaba realmente por el cable). Los desarrolladores experimentados usarían el patrón de fachada para proporcionar una interfaz de grano muy grueso al cliente. Esta fachada a su vez haría múltiples llamadas a diferentes métodos más finos. En general, esto redujo en gran medida el número de llamadas a los métodos requeridos y un mayor rendimiento.
Supongamos que tiene una clase de forma abstracta con una funcionalidad de dibujo (genérica / abstraída) y un círculo que implementa la forma. El patrón de puente simplemente es un enfoque de abstracción de dos vías para desacoplar la implementación (dibujar en Círculo) y la funcionalidad genérica / abstracta (dibujar en la clase Forma).
que significa realmente? A primera vista, parece algo que ya estás haciendo (por inversión de dependencia). Así que no te preocupes por tener una base de código menos modular o más modular. Pero hay una filosofía un poco más profunda detrás de esto.
Desde mi punto de vista, la necesidad del patrón de uso puede surgir cuando necesito agregar nuevas clases que están estrechamente relacionadas con el sistema actual (como RedCircle o GreenCircle) y que difieren en una sola funcionalidad (como el color). Y voy a necesitar el patrón Bridge especialmente si las clases de sistema existentes (Circle o Shape) van a cambiar con frecuencia y no quiere que las clases recién agregadas se vean afectadas por esos cambios. Por eso, la funcionalidad de dibujo genérico se abstrae en una nueva interfaz para que pueda modificar el comportamiento del dibujo independientemente de Shape o Circle.
http://en.wikipedia.org/wiki/Adapter_pattern
El patrón de Adaptador se trata más de hacer que su código existente funcione con un sistema o interfaz más nuevo.
Si tiene un conjunto de API de servicios web estándar de la compañía que le gustaría ofrecer a la interfaz de extensibilidad existente de otra aplicación, puede considerar escribir un conjunto de adaptadores para hacerlo. Tenga en cuenta que hay un área gris y esto se trata más de cómo usted define técnicamente el patrón, ya que otros patrones como la fachada son similares.
http://en.wikipedia.org/wiki/Bridge_pattern
El patrón Bridge le permitirá posiblemente tener implementaciones alternativas de un algoritmo o sistema.
Aunque no es un clásico ejemplo de patrón Bridge, imagínese si tuviera algunas implementaciones de un data store: una es eficiente en espacio, la otra es eficiente en rendimiento bruto ... y tiene un caso de negocio para ofrecer tanto en su aplicación como en su marco .
En términos de su pregunta, "dónde puedo usar qué patrón", la respuesta es: ¡donde sea que tenga sentido para su proyecto! Quizás considere ofrecer una edición de aclaración para guiar la discusión sobre dónde cree que necesita usar una u otra.
Adaptador:
- Es un patrón estructural
- Es útil trabajar con dos interfaces incompatibles
Diagrama UML: del artículo de dofactory :
Objetivo : define la interfaz específica del dominio que usa el Cliente.
Adaptador : adapta la interfaz adaptada a la interfaz de destino.
Adaptado : define una interfaz existente que necesita adaptación.
Cliente : colabora con objetos que se ajustan a la interfaz de Target.
Ejemplo:
Square y Rectangle son dos formas diferentes y obtener area () de cada uno de ellos requiere diferentes métodos. Pero aún así Square trabaja en la interfaz Rectangle con la conversión de algunas de las propiedades.
public class AdapterDemo{
public static void main(String args[]){
SquareArea s = new SquareArea(4);
System.out.println("Square area :"+s.getArea());
}
}
class RectangleArea {
public int getArea(int length, int width){
return length * width;
}
}
class SquareArea extends RectangleArea {
int length;
public SquareArea(int length){
this.length = length;
}
public int getArea(){
return getArea(length,length);
}
}
Puente:
- Es un patrón estructural
- desacopla una abstracción de su implementación y ambos pueden variar de forma independiente
- Es posible porque la composición se ha utilizado en lugar de la herencia
EDITAR: (según la sugerencia de @quasoft)
Tienes cuatro componentes en este patrón.
Abstracción : define una interfaz
RefinedAbstraction : implementa la abstracción:
Implementor : define una interfaz para la implementación
ConcreteImplementor : Implementa la interfaz Implementor.
Fragmento de código:
Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();
gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();
Publicación relacionada:
¿Cuándo usas el patrón de puente? ¿Cómo es diferente del patrón del Adaptador?
Diferencias clave: del artículo de sourcemaking de sourcemaking
- El adaptador hace que las cosas funcionen una vez que están diseñadas; Bridge los hace funcionar antes que ellos.
- Bridge está diseñado desde el principio para permitir que la abstracción y la implementación varíen de forma independiente. El adaptador está adaptado para hacer que las clases no relacionadas funcionen juntas.