Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Le pattern Stratégie

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Par ITERATIF (Olivier Bugalotto)

Attention: l'exemple prit ici n'est que pédagogique.

Important: Ne partez pas du principe que les designs patterns doivent être utilisés au moment de la conception mais plutot pendant l'implémentation de votre code. Lorsque vous rencontrez un probleme donné vérifiez s'il y a pas un pattern qui peut le resoudre.

Ne faites pas comme certains : “Aller je vais faire un framework avec les patterns…” parce qu'ils ont tout faux …

Un pattern est une solution a un probleme donné et il doit être adapter à la tehnologie utilisée. Voici un exemple : Le pattern Observer est à l'origine un moyen de pallier le manque dans des technologies non évènementielles ce qui est le cas de java mais pas de celui d'Actionscript (AsBroadcaster…) donc son implémentation en Actionscript est ridicule ;)

Ceci etant clarifier passons au pattern Stratégie.

Les algorithmes evoluent 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 schéma représentatif:

Design pattern Strategy

Par ITERATIF - BUGALOTTO Olivier (2006) Vous pouvez retrouver ce tutorial et des commentaires à ce sujet sur mon blog