2010-08-13 16 views
18

Quando è necessario utilizzare il modello adattatore? Se possibile, mi dia un esempio reale che si adatta quel modello ...quando è necessario il modello dell'adattatore?

+0

Avete in programma di esaminare l'intero libro GoF e chiedere quando avete bisogno di X pattern? –

+0

Fintanto che gli dà tutti quei upvotes, se fossi in lui vorrei chiedere su ogni modello di design :-P –

+0

@Thomas Owens: Tutto quello che cerco è un buon esempio del mondo reale che mi aiuterà a conoscere quel modello . – brainless

risposta

33

Ho lavorato su un sistema che doveva interfacciarsi con DVR esterni. Per la maggior parte, tutti i DVR hanno le stesse funzionalità di base: avviare la registrazione da una determinata sorgente video; interrompere la registrazione; avvia la riproduzione da un certo tempo; interrompere la riproduzione, ecc.

Ogni produttore di DVR ha fornito una libreria software, che ci ha permesso di scrivere codice per controllare il loro dispositivo (per ragioni di questa discussione, farò riferimento ad esso come SDK). Anche se tutti gli SDK hanno fornito le API per tutte le funzionalità di base, nessuna di esse era la stessa. Ecco un esempio molto approssimativo, ma ti viene l'idea:

  • BeginPlayback (DateTime startTime);
  • StartPlayback (long startTimeTicks);
  • Riproduzione (stringa startDate, stringa startTime);

Il nostro software doveva essere in grado di interagire con tutti i DVR. Così, invece di scrivere orribili interruttore/casi per ogni SDK diverso, abbiamo creato il nostro interfaccia comune IDVRController, e ha scritto tutto il nostro codice del sistema a tale interfaccia:

  • riproduzione (DateTime startTime);

Abbiamo quindi scritto una diversa implementazione dell'adattatore per ciascun SDK, ognuno dei quali ha implementato la nostra interfaccia IDVRController. Abbiamo usato un file di configurazione per specificare il tipo di DVR a cui il sistema si collegherebbe e un modello di fabbrica per istanziare l'implementatore corretto di IDVRController per quel DVR.

In questo modo, il modello di adattatore ha semplificato il nostro codice di sistema: abbiamo sempre codificato IDVRController.E ci ha permesso di implementare gli adattatori per i nuovi SDK dopo la distribuzione (il nostro riflesso di Factory utilizzato per istanziare l'istanza IDVRController corretta).

+1

Eccellente esempio di vita reale. Mi ha aiutato a capire il vero scopo di questo modello. Ho visto che questo schema è usato principalmente insieme a Service Locater o Factory pattern. – NoobDeveloper

5

Nella programmazione di computer, il modello di adattatore per (spesso indicato come il modello involucro o semplicemente un wrapper) è un modello di progettazione che si traduce un'interfaccia per una classe in un'interfaccia compatibile con . Un adattatore consente alle classi di lavorare insieme che non è possibile a causa delle interfacce incompatibili , fornendo l'interfaccia ai client mentre si utilizza l'interfaccia originale . L'adattatore traduce le chiamate all'interfaccia nelle chiamate all'interfaccia originale e la quantità di codice necessaria per eseguire in genere è di piccole dimensioni. L'adattatore è anche responsabile della trasformazione dei dati in moduli appropriati. Per esempio, se più valori booleani vengono memorizzati come un singolo intero ma vostro consumatore richiede un 'vero'/'false', l'adattatore sarebbe responsabile per l'estrazione dei valori appropriati dalla valore intero.

alt text

Wikipedia !!!

2

pattern Adapter è richiesta seguente scenario:

dire che avete definito un'interfaccia I1 con metodo M1 e M2

C1 e C2 implementa questa interfaccia I1, ora C1 mentre l'attuazione M1 e M2 avete non ha trovato aiuto da altre classi esistenti, quindi è necessario scrivere tutta la logica da soli.

Ora, mentre l'attuazione di classe C2 siete venuti in classe C3 con metodi M3 e M4 che possono essere utilizzati per implementare M1 e M2 per C2 modo di utilizzare quelli M3 e M4 in classe C2 si estende la classe C3 e utilizzare M3 e M4 di C3.

In questo esempio C2 diventa Adapter class e C3 diventa 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

interfaccia esistente

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

implementazione corrente per l'interfaccia Shape

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

Ora consideri che vuoi che la classe Circle si adatti alla nostra interfaccia esistente che in nessun modo possiamo modificare (Scritto da terze parti).

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

Ora abbiamo adattato l'implementazione Circle alla nostra interfaccia Shape. Quindi abbiamo bisogno di un adattatore in quanto sono incompatibili.

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

CircleAdaptor - è l'adattatore per Circle
Circle - è la forma adaptee
- è l'interfaccia di destinazione

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)); 
    } 
} 

Spero che questo dà una migliore idea su quando utilizzarlo.

1

È possibile utilizzare il modello di progettazione dell'adattatore quando si ha a che fare con interfacce diverse con comportamento simile (che di solito significa classi con comportamento simile ma con metodi diversi). Un esempio di questo sarebbe una classe per connettersi a un televisore Samsung e un altro per connettersi a un televisore Sony. Condivideranno comportamenti comuni come il menu aperto, l'avvio della riproduzione, la connessione a una rete e così via, ma ciascuna libreria avrà un'implementazione diversa (con diversi nomi di metodi e firme). Queste diverse implementazioni specifiche del fornitore sono chiamate Adaptee nei diagrammi UML.

Così, nel codice (chiamati client nei diagrammi UML), invece di codificare le chiamate di metodo di ciascun fornitore (o adaptee), si potrebbe quindi creare un'interfaccia generica (chiamati target in Diagrammi UML) per avvolgere questi comportamenti simili e lavorare con un solo tipo di oggetto.

I alimentatori poi implementare l'interfacciabersaglio delegando suo metodo chiamate al Adaptees che vengono passati al adattatori via costruttore.

Per realizzarlo in codice Java, ho scritto un progetto molto semplice utilizzando esattamente lo stesso esempio sopra menzionato utilizzando gli adattatori per gestire più interfacce Smart TV. Il codice è piccolo, ben documentato e autoesplicativo, quindi scavalo per vedere come sarebbe l'implementazione di un mondo reale.

Basta scaricare il codice e importarlo in Eclipse (o il tuo IDE preferito) come progetto Maven. È possibile eseguire il codice eseguendo org.example.Main.java. Ricorda che la cosa importante qui è capire come le classi e le interfacce vengono assemblate insieme per progettare il modello. Ho anche creato alcuni falsi Adaptees nel pacchetto com.thirdparty.libs. Spero che sia d'aiuto!

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

0

Un esempio molto comune del modello dell'adattatore avviene mediante l'Service Provider Interface ed è comunemente usato in un sacco di framework Java EE.

La ragione è di consentire diverse implementazioni di Java EE, ma i programmatori semplicemente codificano le specifiche EE Java piuttosto che qualcosa di specifico dell'implementazione.

Al contrario di qualcosa come la codifica direttamente utilizzando le classi di WebSphere che ti bloccano nell'utilizzo di WebSphere.

O peggio (dalla mia esperienza), Apache HTTP Client e scoprirò più tardi che poiché si è codificati per quell'implementazione piuttosto che la normale HttpUrlConnection devi fare molta ricodifica perché non supporta la versione corrente di TLS che sarebbe stato evitato se lo sviluppatore originale avesse codificato su un'API più stabile e avessimo solo bisogno di aggiornare Java runtime.

Problemi correlati