L'adaptateur

Sébastien MERIC

Pour des raisons de conformité à une norme, pour ne pas dépendre d'une implémentation, pour permettre l'évolutivité de votre projet, il arrive que vous ayez besoin de vous reposer sur une interface ou une API qui n'est pas précisément celle qui vous est fournie. Ce design pattern vous propose de pallier cette problématique.

Synonymes : Encapsulage et Empaquetage.

- Titre : L'adaptateur

- Auteur : Sébastien MERIC

- Parution : 24 avril 2003

- Mise à jour : 19 juin 2020

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Sébastien MERIC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Exploration

- II. Structure

- III. Implémentation

I - Exploration

J'ai récemment rencontré le problème d'un manque de conformité d'un outil par rapport à sa fonction et aux standards proposés par Sun en matière d'utilisation en java. Ma problématique était d'envoyer un mail, l'outil : l'API Java de Lotus qui pour la version que j'utilisais n'était pas conforme à Javamail. Pourquoi aurais-je fait le choix d'empaqueter les outils dans un pattern pour le rendre conforme aux normes Java ? Plusieurs raisons s'offrent à nous :

- le besoin de ne pas dépendre de Lotus pour envoyer les mails puisqu'on ignore de quoi demain pourrait être fait ;

- la probabilité très forte que l'API futur de Lotus se conforme aux normes donc un souci de compatibilité ascendante ;

- et surtout, la connaissance acquise autour de l'API Sun plutôt qu'autour de celle d'IBM. En effet, Javamail est standard et connu par de nombreux développeurs, il dispose de nombreuses documentations et bénéficie d'une importante communauté d'entraide au développement.

Pour diverses raisons, il peut donc être de bon augure de se fixer le développement d'un adaptateur entre les classes clientes et une API qui nous est fournie. Une seule bonne raison pour ne pas le faire, mais elle est de taille et mérite réflexion, sera le temps passé à la réalisation de cet adaptateur (et quand on parle de Javamail, ceci peut devenir rédhibitoire).

II - Structure

La structure est quasiment triviale, il suffit en fait de fournir une classe intermédiaire qui soit conforme à vos attentes. Celle-ci délègue toutes les requêtes qui lui sont faites à l'API fournie. L'API peut donc ne pas être conforme à vos attentes. Il est, comme toujours, préférable de s'appuyer sur la notion d'interface pour ne pas dépendre de l'implémentation même sous cette forme, le diagramme va dans ce sens.

III - Implémentation

Je vais vous fournir une API bidon (on reprend l'exemple du Logger) ou tout est en français et pour laquelle vous voulez être conforme à l'outil log4j un peu plus standard. Je ne reprends qu'une seule méthode pour la démonstration.

com.developpez.adaptateur.LoggerFrancais

/*
* LoggerFrancais.java
*
* Created on 11 mars 2003, 17:18
*/

package java.uml.adaptateur.com.developpez.adaptateur;

public class LoggerFrancais {

/** Creates a new instance of LoggerFrancais */
public LoggerFrancais() {
}

/**
* Log une exception quand elle est levée.
*/
public void erreur(Exception e) {
// ici le code pour logger
throw new RuntimeException("Pas implémentée");
}

}

com.developpez.adaptateur.LoggerAdaptateur

/*
* LoggerAdaptateur.java
*
* Created on 11 mars 2003, 17:22
*/

package java.uml.adaptateur.com.developpez.adaptateur;

/**
*
* @author  smeric
*/
public interface LoggerAdaptateur {
public void error(Exception e);
}

com.developpez.adaptateur.LoggerAdaptateurImpl

/*
* LoggerAdaptateurImpl.java
*
* Created on 11 mars 2003, 17:26
*/

package java.uml.adaptateur.com.developpez.adaptateur;

/**
*
* @author  smeric
*/
public class LoggerAdaptateurImpl implements LoggerAdaptateur {

/** Creates a new instance of LoggerAdaptateurImpl */
public LoggerAdaptateurImpl() {
}

public void error(Excpetion e) {
// ici, on se contente d'appeler la méthode du logger non conforme
// effectuant ce que la méthode error() devrait effectuer.
getLoggerFrancais.erreur(e);
}

private LoggerFrancais getLoggerFrancais() {
if (null == loggerFrancais) {
loggerFrancais= new LoggerFrancais();
}
return loggerFrancais;
}

private LoggerFrancais loggerFrancais; // notre cible

}