Qual è la differenza tra i modelli di ponte e adattatore? Dove posso usare ogni modello?Differenza tra modello di ponte e modello di adattatore
risposta
"Adapter rende le cose funzionano dopo che sono stati progettati;. Ponte li fa lavorare prima che siano [GoF, P219]"
In effetti, il modello di adattatore è utile quando si dispone di codice esistente, sia che si tratti di terze parti , o in-house, ma fuori dal tuo controllo, o comunque non modificabile per soddisfare abbastanza l'interfaccia che ti serve. Ad esempio, disponiamo di un SuperWeaponsArray che può controllare una matrice di dispositivi doomsday.
public class SuperWeaponsArray {
/*...*/
public void destroyWorld() {
for (Weapon w : armedWeapons) {
w.fire();
}
}
}
Grande. Tranne che ci rendiamo conto di avere un dispositivo nucleare nel nostro arsenale che precede di gran lunga la conversione all'interfaccia Arma. Ma ci piacerebbe davvero che funzionasse qui ... quindi cosa facciamo ... incatenarlo!
NukeWeaponsAdaptor - basato sulla nostra classe Nuke, ma che esporta l'interfaccia Weapon. Dolce, ora possiamo sicuramente distruggere il mondo. Sembra un po 'scomodo, ma fa funzionare le cose.
Il modello Bridge è qualcosa che si implementa in anticipo - se sai di avere due gerarchie ortogonali, che fornisce un modo per disaccoppiare l'interfaccia e l'implementazione in modo tale che non si ottiene un numero folle di classi. Supponiamo di avere:
Tipi di file di oggetti MemoryMappedFile e DirectReadFile. Diciamo che vuoi essere in grado di leggere i file da varie fonti (forse implementazioni Linux vs Windows, ecc.). Ponte consente di evitare la liquidazione con:
MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile
downvoted, potresti usare un elenco di codice più astratto? l'esempio è troppo specifico e confuso. –
@omouse upvoted, esempio * codice * non è davvero ciò che rende questa risposta al punto. Per un lettore attento ci sono sufficienti indicazioni per iniziare a distinguere i pattern, quindi tutto sommato - è * una buona risposta. –
potresti fornire un esempio di codice effettivo per il pattern bridge? –
http://en.wikipedia.org/wiki/Adapter_pattern
modello L'adattatore è più su come ottenere il codice esistente per lavorare con un sistema più recente o interfaccia.
Se si dispone di un set di API del servizio Web standard dell'azienda che si desidera offrire all'interfaccia di estensibilità esistente di un'altra applicazione, è possibile scrivere un set di adattatori per eseguire questa operazione. Nota che c'è un'area grigia e questo è più su come tecnicamente definisci il modello, dal momento che altri modelli come la facciata sono simili.
http://en.wikipedia.org/wiki/Bridge_pattern
Il modello ponte sta per consentire di avere possibilmente implementazioni alternative di un algoritmo o sistema.
Anche se non si tratta di un classico esempio di bridge, immagina se hai qualche implementazione di un data store: uno è efficiente nello spazio, l'altro è efficiente nelle prestazioni raw ... e hai un business case da offrire sia in la tua app o framework.
In termini di domanda, "dove posso usare quale modello", la risposta è, ovunque abbia senso per il tuo progetto! Forse considera di offrire una modifica di chiarimento per guidare la discussione su dove ritieni di dover usare l'una o l'altra.
Questo post è stato intorno per un bel po '. Tuttavia, è importante capire che una facciata è in qualche modo simile ad un adattatore, ma non è esattamente la stessa cosa.Un adattatore "adatta" una classe esistente a una classe client solitamente non compatibile. Supponiamo che tu abbia un vecchio sistema di flusso di lavoro che la tua applicazione utilizza come client. La tua azienda potrebbe eventualmente sostituire il sistema del flusso di lavoro con un nuovo "incompatibile" (in termini di interfacce). Nella maggior parte dei casi, è possibile utilizzare il modello di adattatore e il codice di scrittura che effettivamente chiama le nuove interfacce del motore del flusso di lavoro. Un ponte è generalmente usato in un modo diverso. Se si dispone effettivamente di un sistema che deve funzionare con diversi file system (ad es. Disco locale, NFS, ecc.), È possibile utilizzare il pattern bridge e creare un livello di astrazione per lavorare con tutti i file system. Questo sarebbe fondamentalmente un caso d'uso semplice per il modello del ponte. La facciata e l'adattatore condividono alcune proprietà, ma le facciate vengono solitamente utilizzate per semplificare un'interfaccia/classe esistente. Nei primi giorni degli EJB non c'erano chiamate locali per EJB. Gli sviluppatori hanno sempre ottenuto lo stub, lo hanno ristretto e lo hanno definito "pseudo-remoto". Questo spesso causava problemi di prestazioni (specialmente quando venivano chiamati sul filo). Gli sviluppatori esperti utilizzerebbero il modello di facciata per fornire un'interfaccia molto dettagliata al client. Questa facciata quindi effettuerebbe a sua volta più chiamate a diversi metodi a grana fine. Tutto sommato, questo ha ridotto notevolmente il numero di chiamate di metodo richieste e un aumento delle prestazioni.
Sebbene, apparentemente al di fuori dell'ambito di questa domanda, la ponderazione di Adapter & Bridge contro Facade potrebbe essere molto appropriata. – Cody
Adapter:
- Si tratta di un modello strutturale
- È utile lavorare con due interfacce incompatibili
UML Diagram: da dofactory articolo:
target: definisce l'interfaccia specifica del dominio che utilizza client.
adattatore: adatta l'adaptee interfaccia per l'interfaccia di destinazione.
Adaptee: definisce un'interfaccia esistente che deve essere adattata.
Client: collabora con oggetti conformi all'interfaccia di destinazione.
Esempio:
rettangolo e del quadrato sono due forme diverse e la zona ottenere() di ciascuna di esse richiede metodi diversi. Ma ancora Square lavora sull'interfaccia Rectangle con la conversione di alcune proprietà.
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);
}
}
Ponte:
- È schema strutturale
- disaccoppia un'astrazione dalla sua attuazione ed entrambi possono variare indipendentemente
- È possibile perché composizione è stata utilizzata in luogo di successione
EDIT: (come da suggerimento @quasoft)
Ci sono quattro componenti di questo modello.
astrazione: Si definisce un'interfaccia
RefinedAbstraction: Esso implementa l'astrazione:
Implementor: Si definisce un'interfaccia per l'attuazione
ConcreteImpleme: implementa l'interfaccia Implementor.
Snippet di codice:
Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();
gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();
Post correlati:
When do you use the Bridge Pattern? How is it different from Adapter pattern?
differenze fondamentali: da sourcemaking articolo
- L'adattatore fa funzionare le cose dopo che sono state progettate; Bridge li fa funzionare prima di loro.
- Bridge è progettato in anticipo per consentire l'astrazione e l'implementazione variano in modo indipendente. L'adattatore è retrofittato per far funzionare insieme classi non correlate.
Includi l'esempio di auto/camion/cambio dai documenti nella risposta. Grande esempio e analogia. – quasoft
Grazie per il suggerimento. Ho modificato la risposta –
Immagino che tu abbia una classe forma astratta con una funzionalità di disegno (generic/astratta) e un cerchio che implementa la forma. Il bridge pattern è semplicemente un approccio di astrazione bidirezionale per disaccoppiare l'implementazione (disegno in Circle) e la funzionalità generica/astratta (disegnando nella classe Shape).
Che cosa significa veramente? Ad una prima occhiata, suona come qualcosa che stai già facendo (per inversione di dipendenza). Quindi non preoccuparti di avere una base di codice meno ridig o più modulare. Ma è dietro una filosofia un po 'più profonda.
Dalla mia comprensione, la necessità di un modello di utilizzo potrebbe emergere quando ho bisogno di aggiungere nuove classi strettamente correlate con il sistema corrente (come RedCircle o GreenCircle) e che differiscono solo da una singola funzionalità (come il colore).E ho bisogno del pattern Bridge in particolare se le classi di sistema esistenti (Circle o Shape) devono essere cambiate di frequente e non vuoi che le nuove classi aggiunte vengano influenzate da tali cambiamenti. Ecco perché la funzionalità di disegno generica viene estratta in una nuova interfaccia in modo da poter modificare il comportamento del disegno indipendentemente da Shape o Circle.
Bridge è un adattatore migliorato. Bridge include l'adattatore e aggiunge ulteriore flessibilità. Ecco come elementi dalla mappa la risposta di Ravindra tra i modelli:
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
forse prendere in considerazione offrendo una modifica chiarimento per guidare la discussione su dove si crede è necessario utilizzare uno o l'altro. –
http://stackoverflow.com/questions/350404/how-do-the-proxy-decorator-adaptor-and-bridge-patterns-differ – Andrei