Je ne comprends pas du tout le modèle de conception "pont". J'ai parcouru divers sites Web, mais ils n'ont pas aidé.
Quelqu'un peut-il m'aider à comprendre cela?
Je ne comprends pas du tout le modèle de conception "pont". J'ai parcouru divers sites Web, mais ils n'ont pas aidé.
Quelqu'un peut-il m'aider à comprendre cela?
Réponses:
Dans la POO, nous utilisons le polymorphisme de sorte qu'une abstraction peut avoir plusieurs implémentations. Regardons l'exemple suivant:
Une nouvelle exigence a été introduite et doit apporter la perspective d'accélération des trains, alors changez le code comme ci-dessous.
Le code ci-dessus n'est pas maintenable et manque de réutilisabilité (en supposant que nous pourrions réutiliser le mécanisme d'accélération pour la même plate-forme de voie). Le code suivant applique le modèle de pont et sépare les deux abstractions différentes, le transport ferroviaire et l' accélération .
la source
Monorail
car ce n'est pas vraiment deux mots, c'est un seul mot (composé). Un MonoRail serait une sous-classe de Rail au lieu d'un autre type de rail (ce qu'il est). Tout comme nous n'utiliserions pasSunShine
ouCupCake
, ils le seraientSunshine
etCupcake
Bien que la plupart des modèles de conception aient des noms utiles, je trouve que le nom "Bridge" n'est pas intuitif en ce qui concerne ce qu'il fait.
Conceptuellement, vous poussez les détails d'implémentation utilisés par une hiérarchie de classes dans un autre objet, généralement avec sa propre hiérarchie. Ce faisant, vous supprimez une dépendance étroite à l'égard de ces détails d'implémentation et autorisez les détails de cette implémentation à changer.
À petite échelle, je compare cela à l'utilisation d'un modèle de stratégie dans la façon dont vous pouvez brancher un nouveau comportement. Mais au lieu de simplement encapsuler un algorithme comme on le voit souvent dans une stratégie, l'objet d'implémentation est généralement plus rempli de fonctionnalités. Et lorsque vous appliquez le concept à une hiérarchie de classes entière, le modèle plus grand devient un pont. (Encore une fois, déteste le nom).
Ce n'est pas un modèle que vous utiliserez tous les jours, mais je l'ai trouvé utile lors de la gestion d'une explosion potentielle de classes qui peut se produire lorsque vous avez un besoin (apparent) d'héritage multiple.
Voici un exemple concret:
J'ai un outil RAD qui vous permet de déposer et de configurer des contrôles sur une surface de conception, j'ai donc un modèle d'objet comme celui-ci:
Et ainsi de suite, avec peut-être une dizaine de commandes.
Mais une nouvelle exigence est ajoutée pour prendre en charge plusieurs thèmes (look-n-feel). Disons que nous avons les thèmes suivants:
Win32
,WinCE
,WinPPC
,WinMo50
,WinMo65
. Chaque thème aurait différentes valeurs ou implémentations pour les opérations liées au rendu comme DefaultFont, DefaultBackColor, BorderWidth, DrawFrame, DrawScrollThumb, etc.Je pourrais créer un modèle d'objet comme celui-ci:
etc., pour un type de contrôle
etc., pour chaque autre type de contrôle (à nouveau)
Vous avez l'idée - vous obtenez une explosion de classe du nombre de widgets fois le nombre de thèmes. Cela complique le concepteur RAD en lui faisant prendre conscience de chaque thème. De plus, l'ajout de nouveaux thèmes oblige le concepteur RAD à être modifié. De plus, il y a beaucoup d'implémentation commune dans un thème qu'il serait génial d'hériter, mais les contrôles héritent déjà d'une base commune (
Widget
).Donc, ce que j'ai fait, c'est créer une hiérarchie d'objets distincte qui implémente le thème. Chaque widget contiendrait une référence à l'objet qui implémente les opérations de rendu. Dans de nombreux textes, cette classe est suffixée avec un
Impl
mais j'ai dévié de cette convention de dénomination.Alors maintenant, mon
TextboxWidget
look ressemble à ceci:Et je peux faire hériter mes différents peintres de ma base thématique, ce que je ne pouvais pas faire auparavant:
L'une des bonnes choses est que je peux charger dynamiquement les implémentations au moment de l'exécution, ce qui me permet d'ajouter autant de thèmes que je veux sans changer le logiciel de base. En d'autres termes, ma "mise en œuvre peut varier indépendamment de l'abstraction".
la source
Win32TextboxPainter
etWin32ListPainter
d' où je viensWin32WidgetPainter
. Vous pouvez avoir un arbre d'héritage du côté de l'implémentation, mais il devrait être plus générique (peutStaticStyleControlPainter
- êtreEditStyleControlPainter
, etButtonStyleControlPainter
) avec toutes les opérations primitives nécessaires remplacées si nécessaire. C'est plus proche du vrai code sur lequel je basais l'exemple.Le pont a l'intention de dissocier une abstraction de sa mise en œuvre concrète , afin que les deux puissent varier indépendamment:
Le pont y parvient en utilisant la composition:
Remarques supplémentaires sur une confusion fréquente
Ce modèle est très similaire au modèle d'adaptateur: l' abstraction offre une interface différente pour une implémentation et utilise la composition pour ce faire. Mais:
Dans cet excellent ouvrage fondateur sur les modèles de conception, les auteurs observent également que:
la source