Patrons de conception/Pont
Le pont est un patron de conception qui permet de découpler l'interface d'une classe et son implémentation. Ainsi l'interface et l'implémentation peuvent varier séparément.
Attention, à ne pas confondre ce patron avec l'adaptateur. En effet, l'adaptateur est utilisé pour adapter l'interface d'une classe vers une autre interface (donc pour faire en sorte que l'interface d'une ou plusieurs classes ressemble à l'interface d'une classe en particulier).
Le pont est lui utilisé pour découpler l'interface de l'implémentation. Ainsi, vous pouvez modifier ou changer l'implémentation d'une classe sans devoir modifier le code client (si l'interface ne change pas bien entendu).
Exemple : formes géométriques.
Considérons une classe représentant la classe de base de formes géométriques, et ses classes (cercles, rectangles, triangles, ...). Tous les types de formes ont des propriétés communes (une couleur par exemple) et des méthodes abstraites communes (calcul de surface par exemple) implémentées par les classes dérivées (comment calculer la surface d'un cercle, ...).
Toutes les formes peuvent également se dessiner à l'écran.
Mais la façon de dessiner dépend de l'environnement graphique et du système d'exploitation.
Plutôt que d'ajouter une méthode par environnement possible à chacune des formes, le patron de conception Pont suggère de créer une interface séparée pour les primitives de dessin. Cette interface est utilisée par les différentes formes qui alors ne dépendent pas de l'implémentation.
Diagramme de classes UML.
Le patron de conception Pont peut être représenté par le diagramme de classes UML suivant :
Exemples de code.
Le programme Java 5 ci-dessous illustre l'exemple des formes géométriques donné précédemment et affiche :
 API1.cercle position 1.000000:2.000000 rayon 7.500000
 API2.cercle position 5.000000:7.000000 rayon 27.500000
/** "Implémentation" */
interface DrawingAPI
 public void drawCircle(double x, double y, double radius);
/** "Implémentation1" */
class DrawingAPI1 implements DrawingAPI
 public void drawCircle(double x, double y, double radius)
 System.out.printf("API1.cercle position %f:%f rayon %f\n", x, y, radius);
/** "Implémentation2" */
class DrawingAPI2 implements DrawingAPI
 public void drawCircle(double x, double y, double radius)
 System.out.printf("API2.cercle position %f:%f rayon %f\n", x, y, radius);
/** "Abstraction" */
interface Shape
 public void draw(); // bas niveau
 public void resizeByPercentage(double pct); // haut niveau
/** "AbstractionRaffinée" */
class CircleShape implements Shape
 private double x, y, radius;
 private DrawingAPI drawingAPI;
 public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI)
 this.x = x; this.y = y; this.radius = radius; 
 this.drawingAPI = drawingAPI;
 // bas niveau, càd spécifique à une implémentation
 public void draw()
 drawingAPI.drawCircle(x, y, radius);
 // haut niveau, càd spécifique à l'abstraction
 public void resizeByPercentage(double pct)
 radius *= pct;
/** Classe utilisatrice */
class BridgePattern
 public static void main(String[] args)
 Shape[] shapes = new Shape[2];
 shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
 shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());
 for (Shape shape : shapes)
 shape.resizeByPercentage(2.5);
 shape.draw();
interface DrawingAPI {
 function drawCircle($dX, $dY, $dRadius);
class DrawingAPI1 implements DrawingAPI {
 public function drawCircle($dX, $dY, $dRadius) {
 echo "API1.circle at ".$dX.":".$dY." radius ".$dRadius."<br/>";
class DrawingAPI2 implements DrawingAPI {
 public function drawCircle($dX, $dY, $dRadius) {
 echo "API2.circle at ".$dX.":".$dY." radius ".$dRadius."<br/>";
abstract class Shape {
 protected $oDrawingAPI;
 public abstract function draw();
 public abstract function resizeByPercentage($dPct);
 protected function __construct(DrawingAPI $oDrawingAPI) {
 $this->oDrawingAPI = $oDrawingAPI;
class CircleShape extends Shape {
 private $dX;
 private $dY;
 private $dRadius;
 public function __construct(
 $dX, $dY,
 $dRadius,
 DrawingAPI $oDrawingAPI
 parent::__construct($oDrawingAPI);
 $this->dX = $dX;
 $this->dY = $dY;
 $this->dRadius = $dRadius;
 public function draw() {
 $this->oDrawingAPI->drawCircle(
 $this->dX,
 $this->dY,
 $this->dRadius
 public function resizeByPercentage($dPct) {
 $this->dRadius *= $dPct;
class Tester {
 public static function main() {
 $aShapes = array(
 new CircleShape(1, 3, 7, new DrawingAPI1()),
 new CircleShape(5, 7, 11, new DrawingAPI2()),
 foreach ($aShapes as $shapes) {
 $shapes->resizeByPercentage(2.5);
 $shapes->draw();
Tester::main();
Output:
 API1.circle at 1:3 radius 17.5
 API2.circle at 5:7 radius 27.5
class Abstraction
 def initialize(implementor)
 @implementor = implementor
 end
 def operation
 raise 'Implementor object does not respond to the operation method' unless @implementor.respond_to?(:operation)
 @implementor.operation
 end
end
class RefinedAbstraction < Abstraction
 def operation
 puts 'Starting operation...'
 super
 end
end
class Implementor
 def operation
 puts 'Doing neccessary stuff'
 end
end
class ConcreteImplementorA < Implementor
 def operation
 super
 puts 'Doing additional stuff'
 end
end
class ConcreteImplementorB < Implementor
 def operation
 super
 puts 'Doing other additional stuff' 
 end
end
normal_with_a = Abstraction.new(ConcreteImplementorA.new)
normal_with_a.operation
normal_with_b = Abstraction.new(ConcreteImplementorB.new)
normal_with_b.operation
refined_with_a = RefinedAbstraction.new(ConcreteImplementorA.new)
refined_with_a.operation
refined_with_b = RefinedAbstraction.new(ConcreteImplementorB.new)
refined_with_b.operation

Patrons de conception/Façade
Le patron de conception façade a pour but de cacher une conception et une interface ou un ensemble d'interfaces complexes difficiles à comprendre (cette complexité étant apparue "naturellement" avec l'évolution du sous-système en question).
La façade permet de simplifier cette complexité en fournissant une interface simple du sous-système.
Habituellement, la façade est réalisée en réduisant les fonctionnalités de ce dernier mais en fournissant toutes les fonctions nécessaires à la plupart des utilisateurs.
La façade encapsule la complexité des interactions entre les objets métier participant à un workflow.
L'utilisation d'une façade a les avantages suivants :
Un adaptateur est utilisé quand la façade doit respecter une interface particulière et doit supporter un comportement polymorphique.
Diagramme des classes UML.
Le patron de conception Façade peut être représenté par le diagramme de classe UML suivant :
Exemple.
Java.
L'exemple suivant cache une API de gestion de calendrier compliquée, derrière une façade plus simple. Il affiche :
 Date : 1980-08-20
 20 jours après : 1980-09-09
import java.util.*;
/* Façade */
class UserfriendlyDate
 GregorianCalendar gcal;
 public UserfriendlyDate(String isodate_ymd)
 String[] a = isodate_ymd.split("-");
 gcal = new GregorianCalendar(
 Integer.parseInt(a[0]), // année
 Integer.parseInt(a[1])-1, // mois (0 = Janvier)
 Integer.parseInt(a[2]) ); // jour
 public void addDays(int days)
 gcal.add(Calendar.DAY_OF_MONTH, days);

public String toString()
 return String.format("%1$tY-%1$tm-%1$td", gcal);
/* Classe utilisatrice */
class FacadePattern
 public static void main(String[] args)
 UserfriendlyDate d = new UserfriendlyDate("1980-08-20");
 System.out.println("Date : "+d);
 d.addDays(20);
 System.out.println("20 jours après : "+d);