Les derniers articles
Le design pattern Strategy
Date :: 2004-11-19
Last Updated :: 2004-12-05
Introduction
Le design pattern Strategy définit une famille d'algorithmes encapsulés et interchangeables. Strategy laisse l'algorithme varier indépendamment du client qui l'utilise. C'est une solution à envisager lorsqu'un problème peut être résolu par différents algorithmes.
Un exemple courant de son implémentation est la localisation d'application. Nous allons voir comment le mettre en oeuvre dans cette optique.
Cas d'utilisations envisageables :
- plusieurs classes différant seulement dans leur comportement,
- vous avez besoin de plusieurs variantes d'un algorithme,
- un algorithme utilise des données que le client ne devrait pas connaître,
- une classe définit plusieurs comportements lesquels nécessitant de nombreux tests conditionnels.
Description
Pour implémenter le design pattern Strategy vous devez commencer par définir une interface commune à tous les algorithmes qui devra être implémentée par toutes les stratégies concrètes. Ensuite, vous pourrez définir au fur et à mesure, et selon vos besoins, différentes stratégies concrètes implémentant l'interface prédéfinie.
L'interface
interface localisation {
public function __construct();
public function currency($euro);
public function translation($refstring);
}
?>
La strategie concrète
La classe de base va implémenter les méthodes nécessaires à la localisation par défaut de notre application. Nous allons créer une méthode formatant la monnaie pour le français (nous avons pris le franc exprès dans un premier temps), et une autre méthode qui sera utilisée pour la traduction des textes français.
Cette classe se compose donc des deux méthodes membre suivantes :
- currency( $float ) : formate la monnaie de référence passée en argument pour la monnaie française,
- translation( $string ) : retourne la traduction de la chaîne de référence passée en argument.
Cette classe suffit pour démarrer votre application avec la localisation de base : le français.
class france implements localisation {
protected $trans = array();
function __construct() {
$this->trans['price'] = 'Le prix est de ';
}
function currency($euro) {
return sprintf('%01.2fFF',$euro*6.55957);
}
function translation($transref) {
return $this->trans[$transref];
}
}
?>
Nous pouvons, sur le même modèle, créer une localisation Anglaise :
class uk implements localisation {
protected $trans = array();
function __construct() {
$this->trans['price'] = 'The price is ';
}
function currency($euro) {
return sprintf('¤%01.2f',$euro/0.7);
}
function translation($transref) {
return $this->trans[$transref];
}
}
?>
Nous pouvons utiliser ces classes comme suit :
$local = new france;
echo $local->translation('price').$local->currency(14.5)."\n";
$local = new uk;
echo $local->translation('price').$local->currency(14.5)."\n";
?>
Mutualiser les traitements.
Les strategies concrètes peuvent partager des quantités non négligeables de traitements. Dans ce cadre on peut vouloir mutualiser ceci en profitant des héritages et du polymorphisme. Supposons les localisations européennes, allemande et espagnole, qui partagent la même monnaie. Pour alléger le code il est bien sûr envisageable de déclarer une classe euro et d'en faire hériter des classes euro_de et euro_es specialisant la classe de base en ajoutant le traitement de traduction.
La localisation européenne :
class euro implements localisation {
protected $trans = array();
function __construct() {
}
function currency($euro) {
return sprintf('¤%01.3f',$euro);
}
function translation($transref) {
return $this->trans[$transref];
}
}
?>
La localisation espagnole :
class euro_es extends euro {
function __construct() {
$this->trans['price'] = 'el precio es ';
}
}
?>
La localisation allemande :
class euro_de extends euro {
function __construct() {
$this->trans['price'] = 'das preiz ist ';
}
}
?>
$local = new euro_de;
echo $local->translation('price').$local->currency(14.5)."\n";
$local = new euro_es;
echo $local->translation('price').$local->currency(14.5)."\n";
?>
Conclusion
L'implémentation du design pattern Strategy permet de régler assez élégamment des problèmes nécessitant la mise en oeuvre de plusieurs algorithmes. Sans cette technique, l'utilisation de multiples structures conditionnelles est incontournable et rend vite le code lourd et peu maintenable.
Fabrice Lezoray < fabrice AT scriptsphp.org >, Tetsuo Shima < tetsuo AT scriptsphp.org >, merci à Microtom pour la relecture et les tests.
Trackback
Il n'y a pas de trackback recensé pour cet article.
Faire un trackback sur cet article http://classes.scriptsphp.org/Trackbackserver.Le-design-pattern-Strategy, récupérer les trackback sur cet article