Quelle est la différence entre les patrons de conception Bridge et Adapter?
Voté vers le bas, pourriez-vous utiliser une liste de code plus abstraite ? L'exemple est trop spécifique et est confus.
Quelle est la différence entre les patrons de conception Bridge et Adapter?
« Adapter permet de faire fonctionner les choses après leur conception ; Bridge permet de les faire fonctionner avant qu'elles ne le soient. [GoF, p219] »
De manière efficace, le motif Adapter est utile lorsque vous disposez de code existant, qu'il s'agisse de code tiers ou interne, mais hors de votre contrôle, ou autrement non modifiable pour répondre exactement à l'interface dont vous avez besoin. Par exemple, nous avons un SuperWeaponsArray qui peut contrôler une excellente variété d'engins de destruction massive.
public class SuperWeaponsArray {
/*...*/
public void destroyWorld() {
for (Weapon w : armedWeapons) {
w.fire();
}
}
}
Génial. Sauf que nous réalisons que nous avons un dispositif nucléaire dans notre arsenal qui date de bien avant la conversion en interface Weapon. Mais nous aimerions vraiment qu'il fonctionne ici... alors que faisons-nous... nous l'intégrons de force !
NukeWeaponsAdaptor - basé sur notre classe Nuke, mais exportant l'interface Weapon. Super, maintenant nous pouvons sûrement détruire le monde. Cela semble un peu bricolé, mais cela permet de faire fonctionner les choses.
Le motif Bridge est quelque chose que vous mettez en œuvre dès le départ - si vous savez que vous disposez de deux hiérarchies orthogonales, il offre un moyen de découpler l'interface et l'implémentation de telle sorte que vous n'obtenez pas un nombre insensé de classes. Disons que vous avez :
Des objets de fichier de types MemoryMappedFile et DirectReadFile. Disons que vous souhaitez être capable de lire des fichiers à partir de différentes sources (peut-être des implémentations Linux vs Windows, etc.). Bridge vous aide à éviter de vous retrouver avec :
MemoryMappedWindowsFile MemoryMappedLinuxFile DirectReadWindowsFile DirectReadLinuxFile
Voté vers le bas, pourriez-vous utiliser une liste de code plus abstraite ? L'exemple est trop spécifique et est confus.
@omouse a voté, par exemple le code n'est vraiment pas ce qui rend cette réponse pertinente. Pour un lecteur attentif, il y a suffisamment d'indications pour commencer à distinguer les motifs, donc dans l'ensemble - c'est une bonne réponse.
http://en.wikipedia.org/wiki/Adapter_pattern
Le pattern Adaptateur concerne davantage la mise en place de votre code existant pour qu'il fonctionne avec un système ou une interface plus récente.
Si vous disposez d'un ensemble d'API de services web standard de l'entreprise que vous souhaitez offrir à l'interface d'extensibilité existante d'une autre application, vous pourriez envisager d'écrire un ensemble d'adaptateurs pour ce faire. Notez qu'il y a une zone grise et il s'agit davantage de la façon dont vous définissez techniquement le pattern, puisque d'autres patterns comme la façade sont similaires.
http://en.wikipedia.org/wiki/Bridge_pattern
Le pattern Bridge va vous permettre d'avoir éventuellement des implémentations alternatives d'un algorithme ou d'un système.
Bien que ce ne soit pas un exemple classique du pattern Bridge, imaginez si vous aviez quelques implémentations d'un magasin de données : l'une est efficace en termes d'espace, l'autre est efficace en termes de performances brutes... et vous avez un cas d'utilisation pour offrir les deux dans votre application ou votre framework.
En ce qui concerne votre question, "où puis-je utiliser tel ou tel pattern", la réponse est, où cela a du sens pour votre projet ! Peut-être envisagez-vous de proposer une édition de clarification pour guider la discussion sur l'endroit où vous pensez avoir besoin d'utiliser l'un ou l'autre.
Adaptateur :
Exemple :
Le carré et le rectangle sont deux formes différentes et obtenir la surface() de chacun d'eux nécessite des méthodes différentes. Mais le carré fonctionne toujours sur l'interface Rectangle en convertissant certaines des propriétés.
public class AdapterDemo{
public static void main(String args[]){
SquareArea s = new SquareArea(4);
System.out.println("Zone du carré :"+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);
}
}
Pont :
Vous avez quatre composants dans ce motif comme expliqué dans le livre Gang of Four Design patterns (page : 174)
Abstraction
: définit l'interface de l'abstraction
AbstractionRaffinée
: étend l'interface définie par Abstraction
Implémenteur
: définit l'interface des classes d'implémentation
ImplémenteurConcret
: implémente l'interface Implémenteur et définit son implémentation concrète.
Référez-vous au code dans le post SE ci-dessous :
Quand utiliser le motif Pont et en quoi est-il différent du motif Adaptateur ?
Dans la réponse principale, @James cite une phrase du GoF, page 219. Je pense qu'il vaut la peine de reproduire ici l'explication complète.
Adaptateur versus Pont
Les motifs Adapter et Bridge ont des attributs communs. Les deux favorisent la flexibilité en fournissant un niveau d'indirection vers un autre objet. Les deux impliquent de transférer les demandes à cet objet depuis une interface autre que la sienne.
La principale différence entre ces motifs réside dans leurs intentions. L'Adaptateur se concentre sur la résolution des incompatibilités entre deux interfaces existantes. Il ne se concentre pas sur la manière dont ces interfaces sont mises en œuvre, et ne considère pas non plus comment elles pourraient évoluer indépendamment. C'est une manière de faire travailler ensemble deux classes conçues indépendamment sans réimplémenter l'une ou l'autre. En revanche, le Pont, relie une abstraction et ses (potentiellement nombreux) implémentations. Il fournit une interface stable aux clients tout en vous permettant de faire varier les classes qui l'implémentent. Il prend également en compte de nouvelles implémentations au fur et à mesure que le système évolue.
En raison de ces différences, l'Adaptateur et le Pont sont souvent utilisés à différents moments du cycle de vie du logiciel. Un adaptateur devient souvent nécessaire lorsque vous découvrez que deux classes incompatibles doivent fonctionner ensemble, généralement pour éviter de répliquer du code. Le couplage est imprévu. En revanche, l'utilisateur d'un pont comprend dès le départ qu'une abstraction doit avoir plusieurs implémentations, et que les deux peuvent évoluer de manière indépendante. Le motif Adaptateur fait fonctionner les choses après qu'elles soient conçues; le Pont les fait fonctionner avant. Cela ne signifie pas que l'Adaptateur est inférieur au Pont; chaque motif aborde simplement un problème différent.
Ce post existe depuis un certain temps. Cependant, il est important de comprendre qu'une façade est quelque peu similaire à un adaptateur, mais ce n'est pas tout à fait la même chose. Un adaptateur "adapte" une classe existante à une classe cliente généralement non compatible. Prenons l'exemple d'un ancien système de workflow que votre application utilise en tant que client. Votre entreprise pourrait éventuellement remplacer le système de workflow par un nouveau système "incompatible" (en termes d'interfaces). Dans la plupart des cas, vous pourriez utiliser le modèle d'adaptateur et écrire du code qui appelle effectivement les interfaces du nouveau moteur de workflow. Un pont est généralement utilisé d'une manière différente. Si vous avez effectivement un système qui doit fonctionner avec différents systèmes de fichiers (par exemple, disque local, NFS, etc.) vous pourriez utiliser le modèle de pont et créer une couche d'abstraction pour travailler avec tous vos systèmes de fichiers. Ce serait en quelque sorte un cas d'utilisation simple pour le modèle de pont. La façade et l'adaptateur ont certaines propriétés en commun mais les façades sont généralement utilisées pour simplifier une interface/classe existante. Au début des EJBs, il n'y avait pas d'appels locaux pour les EJBs. Les développeurs obtenaient toujours le stub, le restreignaient et l'appelaient "pseudo-à distance". Cela causait souvent des problèmes de performance (surtout lorsqu'ils étaient vraiment appelés par le réseau). Les développeurs expérimentés utiliseraient le modèle de façade pour fournir une interface très grossière au client. Cette façade ferait ensuite plusieurs appels à différentes méthodes plus fines. Dans l'ensemble, cela réduisait considérablement le nombre d'appels de méthode requis et améliorait les performances.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Peut-être envisager d'offrir une édition de clarification pour orienter la discussion sur l'endroit où vous pensez avoir besoin d'utiliser l'un ou l'autre.
0 votes
stackoverflow.com/questions/350404/…
0 votes
Aucune explication ici ne remplacera jamais la lecture de Design Patterns: Elements of Reusable Object-Oriented Software