Le design pattern Bridge
Description
Le but du design pattern Bridge est de séparer une abstraction de son implémentation afin que les deux évoluent indépendamment.
Exemple
Pour effectuer une demande d’immatriculation d’un véhicule d’occasion, il convient de préciser sur cette demande certaines informations importantes comme le numéro de la plaque existante. Le système affiche un formulaire pour demander ces informations.
Il existe deux implémentations des formulaires :
-
Les formulaires HTML ;
-
Les formulaires basés sur des widgets Qt.
Il est donc possible d’introduire une classe abstraite FormulaireImmatriculation et deux sous-classes concrètes FormulaireImmatriculationHtml et FormulaireImmatriculationQt.
Dans un premier temps, les demandes d’immatriculation ne concernaient que la France. Par la suite, il est devenu nécessaire d’introduire une nouvelle sous-classe de FormulaireImmatriculation correspondant aux demandes d’immatriculation au Luxembourg, sous-classe appelée FormulaireImmatriculationLux. Cette sous-classe doit également être abstraite et avoir également deux sous-classes concrètes pour chaque implémentation. La figure 11.1 montre le diagramme de classes correspondant.
Figure 11.1 - Hiérarchie des formulaires intégrant les sous-classes d’implémentation
Ce diagramme met en avant deux problèmes :
-
La hiérarchie mélange au même niveau implémentations et abstractions.
-
Les clients sont dépendants d’implémentations...
Structure
1. Diagramme de classes
La figure 11.3 détaille la structure générique du design pattern Bridge.
Figure 11.3 - Structure du design pattern Bridge
2. Participants
Les participants au design pattern Bridge sont les suivants :
-
ClasseAbstraite (AbstractFormulaireImmatriculation) est la classe abstraite qui représente les objets du domaine. Elle décrit l’interface pour les clients et contient une référence vers un objet se conformant à l’interface Implantation.
-
ClasseConcrete (FormImmatriculationFrance et FormImma-triculationLuxembourg) est la classe concrète qui implémente les méthodes contenues dans ClasseAbstraite.
-
Implantation (FormulaireInterface) définit l’interface des classes d’implémentation. Les méthodes de cette interface ne doivent pas correspondre aux méthodes de ClasseAbstraite. Les deux ensembles de méthodes sont différents. L’implémentation introduit en général des méthodes de bas niveau et les méthodes de ClasseAbstraite sont des méthodes de haut niveau.
-
ImplantationA, ImplantationB (FormHtml, FormQt) sont des classes concrètes qui réalisent les méthodes présentes dans l’interface Implantation.
3. Collaborations
Les opérations de ClasseAbstraite et de ses sous-classes invoquent les méthodes...
Domaines d’application
Le design pattern Bridge est utilisé dans les cas suivants :
-
Pour éviter une liaison forte entre la représentation des objets et leur implémentation.
-
Pour que les changements dans l’implémentation des objets n’aient pas d’impact dans les interactions entre les objets et leurs clients.
-
Pour permettre à la représentation des objets et à leur implémentation de conserver leur capacité d’extension par la création de nouvelles sous-classes.
-
Pour éviter d’obtenir des hiérarchies de classes extrêmement complexes comme illustré à la figure 11.1.
Exemple en PHP
Nous décrivons maintenant un exemple en PHP basé sur le diagramme de classes de la figure 11.2.
Nous commençons par l’interface FormulaireInterface décrivant l’implémentation des formulaires. Cette interface contient deux méthodes, l’une pour afficher un texte et l’autre pour gérer une zone de saisie.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge;
interface FormulaireInterface
{
public function dessineTexte(string $texte): void;
public function gereZoneSaisie(): string;
}
Nous nous intéressons maintenant à la classe d’implémentation FormHtml qui simule l’affichage et la saisie d’un formulaire HTML.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge;
class FormHtml implements FormulaireInterface
{
public function dessineTexte(string $texte): void
{
echo "HTML : $texte" . PHP_EOL;
}
public function gereZoneSaisie(): string
{
$fp = fopen("php://stdin", 'r');
$line = rtrim(fgets($fp, 1024));
return $line;
}
}
Nous montrons la classe d’implémentation FormQt qui simule l’affichage et la saisie d’un formulaire à l’aide de widgets Qt.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge; ...