Implementation du pattern décorateur en trois temps en partant d'un code imparfait.

Soyez le premier à donner votre avis sur cette source.

Vue 8 177 fois - Téléchargée 2 496 fois

Description

Ben d'abord on a trois classes d'animaux avec leurs signature propres pour se nourrir et se deplacer
Le pretexte est un scenario ou chaque animal a une heure pour manger et une pour se déplacer.
Il s'agit d'une boucle sur les heures et quand son heure de manger ou de se deplacer arrive, l'animal s'execute.
(tout par des sorties standard, le but est de voir l'évolution du code.

Premier temps:
les oiseaux volent et mangent des graines
Les chats marchent et mangent de la viande
Les poissons nagent et mangent des algues

Deuxieme temps:
On abstrait une classe AbstractAnimal avec methodes Manger et seDeplacer génerique (abstraites)
Les trois especes d'animaux héritent de la classe abstraite et les methodes abstraites sont implementees pour permettre le meme appel de méthode pour se deplacer et se nourrir.
à chaque iteration de la boucle des heures, on test pour chaque animal si c'est son heure de manger ou de se deplacer.

Troisieme temps
On ne veut plus tester si c'est l'heure pour l'animal de se deplacer ou de manger, alors on le décore avec les methodes de controle de l'heure, pour qu'il se gere tout seul --> Classe Decorateur animalier

Le décorateur doit pouvoir se substituer à tout, il implemente donc toutes les méthodes et possede les proprietes plus celles qu'on veut apporte en amélioration.

Source / Exemple :


//premiere version du scenario (extrait)
public void deroulerJournee(){
	    //le chat mange à 6h00 et marche à 10h00
	    //le poisson nage à 12h00 et mange 13h00
	    //l'oiseau vole à 5h00 et mange à 19h00
	chat=new Chat("Minou");
	chat.setHeureDeplacement(10);
	chat.setHeureRepas(6);
	
	oiseau=new Oiseau("Birdy");
	oiseau.setHeureDeplacement(5);
	oiseau.setHeureRepas(19);
	
	poisson=new Poisson("Flipper");
	poisson.setHeureDeplacement(12);
	poisson.setHeureRepas(13);
	do  {
	    System.out.println("Il est "+heure+"h00");
		//on teste l'heure à la place des animaux, ce qui reste encore redondant
		//La decoration permettra de palier ce point.
	    if (chat.getHeureDeplacement()==heure)chat.marcher();
	    if (chat.getHeureRepas()==heure)chat.mangerViande();
	    if (oiseau.getHeureDeplacement()==heure)oiseau.voler();
	    if (oiseau.getHeureRepas()==heure)oiseau.mangerGraines();
	    if (poisson.getHeureDeplacement()==heure)poisson.nager();
	    if (poisson.getHeureRepas()==heure)poisson.mangerAlgues();
	    System.out.println("");
	    
	heure=(heure+1)%24;    
	}while (heure > this.heureAube);
    }

//deuxieme version
public void deroulerJournee(){
	
	//le chat marche à 10h00 et mange à 6h00
	chat=new Chat("Minou",10,6);

	 //l'oiseau vole à 5h00 et mange à 19h00
	oiseau=new Oiseau("Birdy",5,19);

	//le poisson nage à 12h00 et mange 13h00
	poisson=new Poisson("Flipper",12,13);

	AbstractAnimal[] bestiaire={chat,oiseau,poisson}
	do  {
	    System.out.println("Il est "+heure+"h00");
	    
		// code avec abstraction avant d'apporter l'autonomie aux animaux
		for(AbstractAnimal bebete:bestiaire){//pour chaque bebete du bestiaire
			//on appelle la mehode de la classe abstraite et c'est la methode adaptée qui se declenchera
		    if (bebete.getHeureDeplacement()==heure)bebete.seDeplacer();
		    if (bebete.getHeureRepas()==heure)bebete.manger();
	    }	    
	    System.out.println("---------------------");

	    heure=(heure+1)%24;    
	}while (heure != this.heureAube);
    }

//troiseme version
    public void deroulerJournee(){
	//le chat marche à 10h00 et mange à 6h00
	chat=new Chat("Minou",10,6);
	//l'oiseau vole à 5h00 et mange à 19h00
	oiseau=new Oiseau("Birdy",5,19);
	//le poisson nage à 12h00 et mange 13h00
	poisson=new Poisson("Flipper",12,13);

	//DecorateurAnimalier[] bestiaire={chatDecore,oiseauDecore,poissonDecore};
	AbstractAnimal[] bestiaire={chat,oiseau,poisson};
	do  {
	    System.out.println("Il est "+heure+"h00");
	    //Le code avec abstraction puis décoration
	    //========================================
	    for(AbstractAnimal bebete:bestiaire){//pour chaque bebete du bestiaire
		
		//on compte sur l'auto gestion de l'emloi du temps par les animaux 
		//apportée par le decorateur pour ne plus tester l'heure.
		DecorateurAnimalier bebeteDecoree=new DecorateurAnimalier(bebete);
		bebeteDecoree.seDeplacer(heure);//le decorateur ajoute " qui a bougé" à petitNom
		bebeteDecoree.manger(heure);//le décorateur ajoute " qui a mangé" à petitNom
	    }

	    heure=(heure+1)%24;    
	}while (heure != this.heureAube);

Conclusion :


Le pattern décorateur ou "wrapper" permet de manipuler des objets, via des méthodes plus evoluees tout en pouvant se substituer à eux.

Codes Sources

A voir également

Ajouter un commentaire Commentaire
Messages postés
3
Date d'inscription
lundi 15 mai 2006
Statut
Membre
Dernière intervention
4 février 2009

Bonne démarche pour découvrir le DP Décorateur et son usage.
Il est vrai que pas mal d'ouvrages existent, mais généralement peu pédagogiques.
L'exemple développé par Pouicky est progressif et permet de cerner l'intérêt du DP.
Question (à 1 paquet de sucres) : à quand l'extension de ces exemples aus autres DP du GoF ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.