|
|
|||||||||||
Un pattern est une solution a un probleme donné et il doit être adapter à la technologie utilisée.
Les algorithmes évoluent et de nouveaux apparaissent pour prendre en compte ces changements nous allons voir toute l’utilité du pattern Stratégie. Nous allons donc créer une classe SortedList qui a pour fonction d’avoir des éléments triés, voici une première implementation:
class SortedList { // Stocke les elements private var items:Array; function SortedList() { // Nous pensons à le creer items = []; } // Ajoute un nouvel element function addItem(item:Object) { // Nous ajoutons un nouvel element // a l'aide de la methode push items.push(item); } // Retire un element existant function removeItemAt(index:Number):Object { // Code pour retirer un element } // Methode permet d'avoir une liste triee function sort() { items.sort(); } }
Cette première approche est interessante parce que nous pourrons la dériver par l’héritage pour spécialiser la manière de trier, exemple :
class QuickSortedList extends SortedList { function sort() { // Algorithme de tri QuickSort } }
Mais une autre solution qui tent plus d’un principe de conception qui est de séparer ceux qui varient de ceux qui restent constants. Nous savons que la seule partie qui évolue est la méthode sort, nous allons donc la sortir de la classe pour la mettre dans une autre classe. Comme il existe plusieurs algorithmes de trie nous allons donc les implémenter dans différentes classes. Maintenant l’idée serait de pouvoir faire ceci :
var list:SortedList = new SortedList(new QuickSort()); list.addItem("Olivier"); list.addItem("Nicolas"); list.addItem("François"); list.addItem("Mélanie"); list.sort(); trace(list); // Sortie : François,Mélanie,Nicolas,Olivier
C’est-à-dire de passer la référence d’une classe de comportement de tri. Nous allons donc programmer une interface et non implémentation à l’aide d’une interface ISort :
interface ISort { function sort(items:Array); }
et ainsi l’implémenter dans des classes de comportement de tri :
class QuickSort implements ISort { function QuickSort() { } // Nous passons la reference d'un table // que nous trirons a l'aide l'algorithme function sort(items:Array) { // Code de l'algorithme // Ici nous lançons le comportement par default // C'est a vous d'implementer un algorithme Quicksort items.sort(); } }
Voici une autre classe qui contient un algorithme qui n’existe pas mais il pourrait
class X11Sort implments ISort { function X11Sort() { } function sort(items:Array) { // Code de l'agorithme X11Sort items.sort(); } }
Maintenant que c’est fait, il nous faut modifier la classe SortedList pour qu’elle accepte la référence d’une classe de tri.
class SortedList { // Stocke les elements private var items:Array; private var strategy:ISort; function SortedList(ISort strategy) { // Nous pensons à le creer items = []; this.strategy = strategy; } // Ajoute un nouvel element function addItem(item:Object) { // Nous ajoutons un nouvel element // a l'aide de la methode push items.push(item); } // Retire un element existant function removeItemAt(index:Number):Object { // Code pour retirer un element } // Methode permet d'avoir une liste triee function sort() { // C'est ici que nous passons le tableau // a la methode sort de notre classe de tri. strategy.sort(items); } }
Ceci permet l’évolution de la classe SortedList par rapport a de nouveaux algorithmes mais sans jamais toucher au comportement constant qui est d’ajouter, retirer ou rechercher un élément dans la liste.
Voici un diagramme UML représentatif:
Par ITERATIF - BUGALOTTO Olivier (2006) Vous pouvez retrouver ce tutorial et des commentaires à ce sujet sur mon blog