Question

Quelqu'un a-t-il déjà utilisé le modèle de pont dans une application réelle? Si oui, comment l'avez-vous utilisé? Est-ce moi, ou est-ce juste le pattern Adapter avec une petite injection de dépendance dans le mix? Mérite-t-il vraiment son propre modèle?

Était-ce utile?

La solution

Un exemple classique du motif Bridge est utilisé dans la définition des formes dans un environnement d'interface utilisateur (voir le Bridge modèle entrée Wikipedia ). Le modèle Bridge est un composite du < a href = "http://en.wikipedia.org/wiki/Template_method_pattern" rel = "noreferrer"> Modèle et Stratégie modèles.

C’est une vue commune de certains aspects du motif Adaptateur du motif Pont. Cependant, pour citer cet article :

  

À première vue, le modèle Bridge ressemble beaucoup au modèle Adapter, dans la mesure où une classe est utilisée pour convertir un type d'interface en un autre. Cependant, l'intention du modèle Adapter est de faire en sorte qu'une ou plusieurs interfaces de classes aient la même apparence que celles d'une classe particulière. Le modèle Bridge est conçu pour séparer l'interface d'une classe de son implémentation afin que vous puissiez modifier ou remplacer l'implémentation sans changer le code client.

Autres conseils

Il existe une combinaison de liens de Federico et de Les réponses de John .

Quand:

                   ----Shape---
                  /            \
         Rectangle              Circle
        /         \            /      \
BlueRectangle  RedRectangle BlueCircle RedCircle

Refactoriser à:

          ----Shape---                        Color
         /            \                       /   \
Rectangle(Color)   Circle(Color)           Blue   Red

Le modèle Bridge est une application de l’ancien conseil "privilégier la composition à l’héritage". Cela devient pratique lorsque vous devez sous-classer différents moments de manière orthogonale. Supposons que vous deviez mettre en place une hiérarchie de formes colorées. Vous ne sous-classeriez pas Shape with Rectangle and Circle puis sous-classe Rectangle avec RedRectangle, BlueRectangle et GreenRectangle et la même chose pour Circle, n'est-ce pas? Vous préféreriez dire que chaque forme a une couleur et mettre en œuvre une hiérarchie de couleurs, à savoir le motif de pont. Eh bien, je ne mettrais pas en place une "hiérarchie de couleurs", mais vous avez l’idée ...

Quand:

        A
     /     \
    Aa      Ab
   / \     /  \
 Aa1 Aa2  Ab1 Ab2

Refactoriser à:

     A         N
  /     \     / \
Aa(N) Ab(N)  1   2

Adaptateur et pont sont certainement liés et la distinction est subtile. Il est probable que certaines personnes qui pensent utiliser l'un de ces modèles utilisent en réalité l'autre modèle.

L’explication que j’ai vue est que l’adaptateur est utilisé lorsque vous essayez d’unifier les interfaces de certaines classes incompatibles qui existent déjà . L'adaptateur fonctionne comme une sorte de traducteur pour les implémentations qui pourraient être considérées comme héritées .

Alors que le modèle Bridge est utilisé pour un code plus susceptible d’être un greenfield. Vous concevez Bridge pour fournir une interface abstraite pour une implémentation devant varier, mais vous définissez également l'interface de ces classes d'implémentation.

Les pilotes de périphérique sont un exemple souvent cité de Bridge, mais je dirais que c'est un pont si vous définissez les spécifications d'interface pour les fournisseurs de périphériques, mais c'est un adaptateur si vous utilisez des pilotes de périphérique existants et créez un wrapper -class pour fournir une interface unifiée.

En termes de code, les deux modèles sont très similaires. Du point de vue commercial, ils sont différents.

Voir aussi http://c2.com/cgi/wiki?BridgePattern

Selon mon expérience, Bridge est un modèle récurrent assez fréquent, car il constitue la solution chaque fois que il existe deux dimensions orthogonales dans le domaine . Par exemple. formes et méthodes de dessin, comportements et plates-formes, formats de fichier et sérialiseurs, etc.

Et un conseil: pensez toujours aux modèles de conception du point de vue conceptuel , et non du point de vue de la mise en œuvre. Du bon point de vue, Bridge ne peut pas être confondu avec Adapter, car ils résolvent un problème différent, et la composition est supérieure à l'héritage, non pas en soi, mais parce qu'elle permet de gérer séparément les problèmes orthogonaux.

L'intention de Bridge et de Adaptateur est différente et nous avons besoin des deux modèles séparément.

Modèle de pont:

  1. C’est un schéma structurel
  2. L'abstraction et l'implémentation ne sont pas liées au moment de la compilation
  3. Abstraction et implémentation - les deux peuvent varier sans impact sur le client
  4. Utilise la composition plutôt que l'héritage.

Utilisez le modèle de pont lorsque:

  1. Vous voulez une liaison d'exécution de l'implémentation,
  2. Vous avez une prolifération de classes résultant d'une interface couplée et de nombreuses implémentations,
  3. vous souhaitez partager une implémentation entre plusieurs objets,
  4. Vous devez mapper des hiérarchies de classes orthogonales.

@ La réponse de John Sonmez montre clairement l’efficacité du modèle de pont pour réduire la hiérarchie des classes.

Vous pouvez vous référer au lien ci-dessous pour en savoir plus sur le modèle de pont avec un exemple de code

Modèle d'adaptateur :

  1. Cela permet à deux interfaces non liées de fonctionner ensemble à travers les différents objets, jouant éventuellement le même rôle.
  2. Il modifie l'interface d'origine.

Principales différences:

  1. Adapter permet aux choses de fonctionner une fois conçues; Bridge les fait fonctionner avant d’être.
  2. Bridge est conçu à l’avance pour permettre à l’abstraction et à la mise en oeuvre de varier indépendamment . Adapter a été ajouté ultérieurement pour que les classes non apparentées fonctionnent ensemble.
  3. L'intention: Adapter permet à deux interfaces non liées de fonctionner ensemble. Bridge permet à l’abstraction et à la mise en oeuvre de varier de manière indépendante.

Question SE associée avec diagramme UML et code de travail:

Différence entre le modèle de pont et le modèle d'adaptateur

Articles utiles:

article de modèle sur le pont de sourcemaking

article de modèle sur l'adaptateur de création de source de contenu

article de modèle du pont de journaldev

EDIT:

Exemple concret Bridge Pattern (selon la suggestion de meta.stackoverflow.com, exemple de site de documentation incorporé dans cet article, car la documentation est sur le point de se coucher)

Le modèle de pont dissocie l’abstraction de la mise en œuvre de sorte que les deux puissent varier indépendamment. Cela a été réalisé avec la composition plutôt que par héritage.

Modèle de pont UML de Wikipedia:

 Modèle de pont UML de Wikipedia

Vous avez quatre composants dans ce modèle.

Abstraction : définit une interface

RefinedAbstraction : Il implémente l'abstraction:

Implementor : définit une interface pour la mise en oeuvre

ConcreteImplementor : Il implémente l'interface Implementor.

Le noeud du modèle Bridge: deux hiérarchies de classes orthogonales utilisant la composition (et pas d'héritage). La hiérarchie d'abstraction et la hiérarchie d'implémentation peuvent varier indépendamment. L'implémentation ne fait jamais référence à l'abstraction. Abstraction contient une interface d'implémentation en tant que membre (via la composition). Cette composition réduit un niveau supplémentaire de hiérarchie d'héritage.

Mot réel Cas d'utilisation:

Autorisez différents véhicules à disposer des deux versions du système de transmission manuelle et automatique.

Exemple

J'ai utilisé le motif de pont au travail. Je programme en C ++, où on l'appelle souvent l'idiome PIMPL (pointeur sur l'implémentation). Cela ressemble à ceci:

class A
{
public: 
  void foo()
  {
    pImpl->foo();
  }
private:
  Aimpl *pImpl;
};

class Aimpl
{
public:
  void foo();
  void bar();
};  

Dans cet exemple, la classe A contient l'interface et la classe Aimpl contient l'implémentation.

L'une des utilisations de ce modèle est d'exposer uniquement certains membres publics de la classe d'implémentation, mais pas les autres. Dans l'exemple, seul Aimpl :: foo () peut être appelé via l'interface publique de A , mais pas Aimpl :: bar ()

Un autre avantage est que vous pouvez définir Aimpl dans un fichier d'en-tête séparé qui n'a pas besoin d'être inclus par les utilisateurs de A . Tout ce que vous avez à faire est d’utiliser une déclaration forward de Aimpl avant de définir Un , puis de déplacer les définitions de toutes les fonctions membres référençant pImpl . le fichier .cpp. Cela vous permet de garder l’en-tête Aimpl privé et de réduire le temps de compilation.

Pour insérer un exemple de forme dans le code:

#include<iostream>
#include<string>
#include<cstdlib>

using namespace std;

class IColor
{
public:
    virtual string Color() = 0;
};

class RedColor: public IColor
{
public:
    string Color()
    {
        return "of Red Color";
    }
};

class BlueColor: public IColor
{
public:
    string Color()
    {
        return "of Blue Color";
    }
};


class IShape
{
public:
virtual string Draw() = 0;
};

class Circle: public IShape
{
        IColor* impl;
    public:
        Circle(IColor *obj):impl(obj){}
        string Draw()
        {
            return "Drawn a Circle "+ impl->Color();
        }
};

class Square: public IShape
{
        IColor* impl;
    public:
        Square(IColor *obj):impl(obj){}
        string Draw()
        {
        return "Drawn a Square "+ impl->Color();;
        }
};

int main()
{
IColor* red = new RedColor();
IColor* blue = new BlueColor();

IShape* sq = new Square(red);
IShape* cr = new Circle(blue);

cout<<"\n"<<sq->Draw();
cout<<"\n"<<cr->Draw();

delete red;
delete blue;
return 1;
}

Le résultat est:

Drawn a Square of Red Color
Drawn a Circle of Blue Color

Notez la facilité avec laquelle de nouvelles couleurs et formes peuvent être ajoutées au système sans entraîner d'explosion des sous-classes en raison de permutations.

Pour moi, je le considère comme un mécanisme permettant d’échanger des interfaces. Dans le monde réel, vous pourriez avoir une classe pouvant utiliser plusieurs interfaces, Bridge vous permet d’échanger.

Bridge design pattern we can easily understand helping of service and dao layer.

Dao layer -> create common interface for dao layer ->
public interface Dao<T>{
void save(T t);
}
public class AccountDao<Account> implement Dao<Account>{
public void save(Account){
}
}
public LoginDao<Login> implement Dao<Login>{
public void save(Login){
}
}
Service Layer ->
1) interface
public interface BasicService<T>{
    void save(T t);
}
concrete  implementation of service -
Account service -
public class AccountService<Account> implement BasicService<Account>{
 private Dao<Account> accountDao;
 public AccountService(AccountDao dao){
   this.accountDao=dao;
   }
public void save(Account){
   accountDao.save(Account);
 }
}
login service- 
public class LoginService<Login> implement BasicService<Login>{
 private Dao<Login> loginDao;
 public AccountService(LoginDao dao){
   this.loginDao=dao;
   }
public void save(Login){
   loginDao.save(login);
 }
}

public class BridgePattenDemo{
public static void main(String[] str){
BasicService<Account> aService=new AccountService(new AccountDao<Account>());
Account ac=new Account();
aService.save(ac);
}
}
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top