2010-08-13 15 views
18

¿Cuándo tenemos que ir para el patrón del adaptador? Si es posible, dame un ejemplo del mundo real que se adapte a ese patrón ...¿Cuándo necesitamos un patrón de adaptador?

+0

¿Está pensando en revisar todo el libro de GoF y preguntar cuándo necesita el patrón X? –

+0

Mientras le dé todos esos votos por adelantado, si yo fuera él, preguntaría sobre cada patrón de diseño :-P –

+0

@Thomas Owens: Todo lo que busco es un buen ejemplo del mundo real que me ayude a aprender sobre ese patrón . – brainless

Respuesta

33

Trabajé en un sistema que necesitaba una interfaz con DVR externos. En su mayor parte, todos los DVR tienen la misma funcionalidad básica: comenzar a grabar desde una fuente de video determinada; para de grabar; iniciar la reproducción desde un cierto tiempo; detener la reproducción, etc.

Cada fabricante de DVR proporcionó una biblioteca de software, lo que nos permite escribir código para controlar su dispositivo (en aras de esta discusión, me referiré a él como el SDK). A pesar de que cada SDK proporcionaba API para todas las funcionalidades básicas, ninguna de ellas era la misma. Aquí hay un ejemplo muy aproximado, pero se entiende:

  • BeginPlayback (DateTime startTime);
  • StartPlayback (long startTimeTicks);
  • Reproducción (string startDate, string startTime);

Nuestro software necesitaba poder interactuar con todos los DVR. Así que en lugar de escribir interruptor de encendido/casos horribles para cada SDK diferente, hemos creado nuestra propia interfaz IDVRController común, y escribimos todo nuestro sistema de código para esa interfaz:

  • reproducción (DateTime horaInicio);

Luego escribimos una implementación de adaptador diferente para cada SDK, todos los cuales implementaron nuestra interfaz IDVRController. Usamos un archivo de configuración para especificar el tipo de DVR al que se conectaría el sistema, y ​​un patrón de Fábrica para instanciar el implementador correcto de IDVRController para ese DVR.

De esta forma, el patrón del adaptador simplificó el código de nuestro sistema: siempre codificamos para IDVRController.Y nos permitió implementar adaptadores para nuevos SDK después de la implementación (nuestra Factory usó el reflejo para crear la instancia IDVRController correcta).

+1

Excelente ejemplo de la vida real. Me ayudó a comprender el verdadero propósito de este patrón. He visto que este patrón se usa principalmente junto con Service Locater o Factory pattern. – NoobDeveloper

5

En la programación de computadoras, el adapter (a menudo referido como el patrón envoltura o simplemente un envoltorio) es un patrón de diseño que se traduce una interfaz para una clase en una interfaz compatible . Un adaptador permite que las clases trabajen juntas que normalmente no pudieron debido a las interfaces incompatibles , proporcionando su interfaz a los clientes mientras usa la interfaz original. El adaptador traduce las llamadas a su interfaz a llamadas a la interfaz original, y la cantidad de código necesario para hacer esto es típicamente pequeño. El adaptador también es responsable de transformar los datos en los formularios adecuados. Para ejemplo, si varios valores booleanos se almacenan como un único entero, pero su consumidor requiere un 'verdadero'/'falso', el adaptador sería encarga de extraer los valores apropiados de la valor entero.

alt text

Wikipedia !!!

2

adapter se requiere en el siguiente escenario:

Digamos que tiene definida una interfaz I1 con el método M1 y M2

C1 y C2 implementa esta interfaz I1, ahora para C1 mientras que la aplicación M1 y M2 usted tiene no encontró ayuda de otras clases existentes, por lo que necesita escribir toda la lógica usted mismo.

Ahora bien, aunque la implementación de la clase C2 que haya llegado a través de clases C3 con métodos M3 y M4 que se pueden utilizar para implementar M1 y M2 para C2 manera de utilizar los M3 y M4 en clase C2 que extiende la clase C3 y utilizar M3 y M4 de C3.

En este ejemplo se convierte en C2Adapter class y C3 se convierte en adaptee

package com.design.patterns; 

public class AdapterExample { 
    public static void main(String[] args) { 
     Shape line = new LineShape(); 
     line.draw(); 

     Shape text = new TextShape(); 
     text.draw(); 
    } 
} 

//==Start from here 
interface Shape{ 
    public void draw(); 
} 

class LineShape implements Shape{ 
    @Override 
    public void draw() { 
     System.out.println("write some logic and draw line"); 
    } 
} 

//Adapter 
class TextShape extends TextView implements Shape{ 
    @Override 
    public void draw() { 
     System.out.println("logic is already there in class TextView"); 
     drawText(); 
    } 
} 

// Adaptee 
class TextView{ 
    public void drawText() { 
     System.out.println("Drawing Text Shape"); 
    } 
} 
1

interfaz existente

interface Shape { 
    public int calculateArea(int r); 
} 

implementación actual para la interfaz Forma

class Square implements Shape { 
    @Override 
    public int calculateArea(int r) { 
     return r * r; 
    } 
} 

ahora consideran que quiere que la clase Circle se adapte a nuestra interfaz existente que de ninguna manera podemos modificar (Escrito por un tercero).

class Circle { 
    public double calculateCircularArea (int r) { 
     return 3.14 * r * r; 
    } 
} 

Ahora tenemos adaptar la implementación de Círculo a nuestra interfaz de Forma. Entonces, necesitamos un adaptador ya que son incompatibles.

class CirCleAdaptor extends Circle implements Shape { 
    @Override 
    public int calculateArea(int r) { 
     return (int) calculateCircularArea(r); 
    } 
} 

CircleAdaptor - es el adaptador para Circle
Círculo - ¿Es la Forma adaptée
- es la interfaz de destino

public class AdapterPattern { 
    public static void main(String[] args) { 
     Shape circle = new CirCleAdaptor(); 
     System.out.println("Circle Area " + circle.calculateArea(5)); 
     Shape square = new Square(); 
     System.out.println("Square Area " + square.calculateArea(5)); 
    } 
} 

Hope esto le da una mejor idea acerca de cuándo usarlo.

1

Puede utilizar el patrón de diseño del Adaptador cuando tiene que tratar con diferentes interfaces con un comportamiento similar (lo que generalmente significa clases con un comportamiento similar pero con métodos diferentes). Un ejemplo de esto sería una clase para conectarse a un televisor Samsung y otra para conectarse a un televisor Sony. Compartirán un comportamiento común como abrir el menú, iniciar la reproducción, conectarse a una red, etc., pero cada biblioteca tendrá una implementación diferente (con diferentes nombres de método y firmas). Estas diferentes implementaciones específicas del proveedor se llaman Adaptee en los diagramas UML.

Por lo tanto, en el código (llamados cliente en los diagramas UML), en lugar de codificar las llamadas a métodos de cada proveedor (o adaptée), A continuación, podría crear una interfaz genérica (llamados Objetivo en Diagramas UML) para ajustar estos comportamientos similares y trabajar con un solo tipo de objeto.

Los adaptadores luego implementar el interfaz deObjetivo delegar su método llama a los Adaptees que se pasan a los adaptadores través constructor.

Para que se dé cuenta de esto en el código de Java, escribí un proyecto muy simple utilizando exactamente el mismo ejemplo mencionado anteriormente usando adaptadores para tratar con múltiples interfaces de Smart TV. El código es pequeño, está bien documentado y se explica por sí mismo, por lo que puede profundizar para ver cómo sería una implementación en el mundo real.

Simplemente descargue el código e impórtelo a Eclipse (o su IDE favorito) como proyecto de Maven. Puede ejecutar el código ejecutando org.example.Main.java. Recuerde que lo importante aquí es comprender cómo se ensamblan las clases y las interfaces para diseñar el patrón. También creé algunos Adaptees falsos en el paquete com.thirdparty.libs. ¡Espero eso ayude!

https://github.com/Dannemann/java-design-patterns

0

Un ejemplo muy común de la adapter se realiza a través de la Service Provider Interface y se usa comúnmente en una gran parte del marco de Java EE.

El motivo es permitir diferentes implementaciones de Java EE, pero los programadores simplemente codifican las especificaciones de Java EE en lugar de algo específico de la implementación.

A diferencia de algo así como la codificación directamente utilizando clases de WebSphere que lo bloquean al usar WebSphere.

O peor (según mi experiencia), Apache HTTP Client y descubro más tarde que porque ha codificado esa implementación en lugar de la HttpUrlConnection normal, tiene que hacer mucha recodificación porque no admite la versión actual de TLS que se habría evitado si el desarrollador original hubiera codificado una API más estable y solo necesitáramos actualizar el tiempo de ejecución de Java.

Cuestiones relacionadas