2009-09-15 15 views
75

¿Cuál es la diferencia entre los patrones de puente y adaptador? Donde puedo usar cada patrón?Diferencia entre patrón de puente y patrón de adaptador

+0

Tal vez pensar en ofrecer una aclaración de edición para guiar la discusión sobre dónde cree que necesita utilizar uno u otro. –

+0

http://stackoverflow.com/questions/350404/how-do-the-proxy-decorator-adaptor-and-bridge-patterns-differ – Andrei

Respuesta

131

"adaptador hace que las cosas funcionan después de que están diseñados;. Puente hace trabajar antes de que sean [GoF, P219]"

Efectivamente, el patrón adaptador es útil cuando se ha código existente, ya sea de terceros o dentro de la empresa, pero fuera de su control, o de lo contrario no 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(); 
    } 
    } 
} 

Genial. 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 del puente es algo que se implementa en la delantera - si usted sabe que tiene dos jerarquías ortogonales, que proporciona una forma para desacoplar la interfaz y la puesta en práctica de una manera tal que no obtiene un número loco de clases Supongamos que tiene:

MemoryMappedFile y DirectReadFile tipos de objetos de archivo. Digamos que desea poder leer archivos de varias fuentes (implementaciones de Linux frente a Windows, etc.). Puente le ayuda a evitar la liquidación con:

MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile

+5

downvoted, ¿podría utilizar un listado de código más abstracto? el ejemplo es muy específico y es confuso. –

+23

@omouse upvoted, ejemplo * código * realmente no es lo que hace que esta respuesta al grano. Para un lector cuidadoso, hay suficientes indicadores para comenzar a distinguir los patrones, así que, en general, * es * una buena respuesta. –

+13

¿podría proporcionar algún ejemplo de código real para el patrón de puente? –

11

http://en.wikipedia.org/wiki/Adapter_pattern

patrón El adaptador es más sobre cómo obtener su código existente para trabajar con un sistema nuevo o interfaz.

Si tiene un conjunto de API de servicio 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 puente va a permitir que usted tenga posiblemente implementaciones alternativas de un algoritmo o sistema.

Aunque no es un clásico ejemplo de patrón de puente, imagínese si tenía algunas implementaciones de un almacén de datos: uno es eficiente en el espacio, el otro es eficiente en rendimiento bruto ... y tiene un caso de negocio para ofrecer ambos en su aplicación o marco.

En términos de su pregunta, "donde 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.

7

Este post ha sido de alrededor durante 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 sí comparten algunas propiedades, pero las fachadas se suelen usar 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.

+0

Aunque, aparentemente fuera del alcance de esta pregunta, la ponderación de Adapter & Bridge against Facade puede ser muy apropiada. – Cody

4

adaptador:

  1. Es un patrón estructural
  2. Es útil para trabajar con dos interfaces incompatibles

Diagrama UML: de dofactory artículo:

enter image description here

Target: define la interfaz de dominio específico que utiliza Client.

adaptador: adapta la adaptée interfaz a la interfaz de destino.

Adaptee: define una interfaz existente que necesita adaptación.

Client: colabora con objetos acuerdo con la interfaz de destino.

Ejemplo:

cuadrado y del rectángulo son dos formas diferentes y la zona de conseguir() 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:

  1. Es patrón estructural
  2. se desacopla una abstracción de su implementación y ambos pueden variar independientemente
  3. Es posible porque la composición se ha utilizado en lugar de la herencia

EDIT: (según la sugerencia @quasoft)

Tiene cuatro componentes de este patrón.

  1. Abstracción: Define una interfaz

  2. RefinedAbstraction: Se implementa la abstracción:

  3. Implementor: Define una interfaz para la aplicación

  4. ConcreteImpleme ntor: 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(); 

Post relacionados:

When do you use the Bridge Pattern? How is it different from Adapter pattern?

diferencias clave: de sourcemaking artículo

  1. El adaptador hace que las cosas funcionen una vez diseñadas; Bridge los hace funcionar antes que ellos.
  2. El puente está diseñado por adelantado 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.
+0

Incluya el ejemplo de automóvil/camión/engranaje de los documentos en la respuesta. Gran ejemplo y analogía. – quasoft

+0

Gracias por la sugerencia. He editado la respuesta –

0

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).

¿Qué 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.

Según entiendo, la necesidad de un 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) se cambian 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.

0

Puente mejorado Adaptador. Bridge incluye adaptador y le agrega flexibilidad adicional. Aquí es cómo los elementos de mapa de la respuesta de Ravindra entre los 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 
Cuestiones relacionadas