TP2 - Simulation de Nuées

De $1

Version de 01:42, 26 Nov 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Initiateurs : Michel Buffa, Richard Grin, Philippe Collet
Version initiale du code: Philippe Collet
Adaptation et mise à jour: Philippe Renevier-Gonin, Frédéric Mallet

Ce TP est prévu pour durer deux séances.

Introduction

L'application fournit une architecture pour faire des simulations de "bébêtes". Ces bébêtes évoluent dans un espace clos, le simulateur doit permettre de voir leurs déplacements. Une bébête a donc une position, elle se déplace dans une certaine direction avec une vitesse donnée et elle peut voir devant elle avec un certain champ de vision. Elle est censée agir en fonction de son environnement (les bébêtes aux alentours). Vous disposez d’une version de base du projet (code source) et d’un jar permettant d’essayer le résultat final. Vous disposez de deux séances pour réaliser ce tp. A la fin de la première séance, vous devriez être dans la partie IV sur la fabrique de fabriques.

Pour conserver l’évolution du tp, vous pouvez faire pour chaque partie un projet différent dans votre IDE préféré.

Partie I - Prise en main des bébêtes

 Temps estimé: 40 minutes

Vous disposez d’un code de départ qui contient un projet Eclipse:

  • Sous Eclipse, File/Import...
  • Select Existing projects into workspace..., Next
  • Select Archive File and browse to select the .zip file
  • Select "Bebets 01 Debut" and Finish 

Essayons de mettre à plat ensemble les entités simulées à partir du code que nous avons au départ. On peut déjà distinguer un certain nombre de rôles différents dans une bébête:  

  • c'est une entité graphique qui se dessine avec une certaine couleur ;  
  • c'est une entité qui a une certaine position dans un champ ;  
  • c'est une entité qui se déplace et se dirige (vitesse et direction), on distinguera position et déplacement, car on pourrait vouloir mettre des entités positionnées mais inertes dans notre simulateur ;  
  •  c'est une entité qui agit, ou tout du moins qui s'actionne, puisque c'est le "moteur de simulation" qui la fait agir...  

Un champ de bébêtes est l’entité qui « porte » les bébêtes :  

  • un champ possède une certaine dimension ;
  • un champ contient des entités positionnables  ;
  • il y a un moteur de simulation avec un thread qui provoque des pas de simulation et actionne les objets "actionnables" à chaque pas ; 

il y a aussi un moteur d'affichage, plutôt mal fichu, car entièrement couplé avec le moteur de simulation à coup de méthode repaint, alors qu'il serait beaucoup mieux d'avoir un second moteur (donc un second thread) pour la visualisation, indépendamment de la simulation

Question 1

Complétez les diagrammes suivants pour représenter le simulateur. Les diagrammes sont séparés en deux par commodités.

Bebetes.png

champ.png

Question 2

Décrivez en français le comportement des "BebeteEmergente"s et des "BebeteHasard"s.

Question 3

Quelle(s) classe(s) faut-il modifier pour :

  • "nommer" une seule bébête parmi toutes afin de la repérer plus facilement ?
  • associer une image à chaque bébête ?
  • ajouter un nom à toutes les bébêtes ?

Pour les trois questions ci-dessus, on répondra dans le cas où l'on souhaite faire ces actions pour les bébêtes émergentes seulement, pour les bébêtes hasard ou pour toutes les bébêtes indifféremment.  

Est-ce que ces actions sont liées à la spécificité (émergente ou hasard) de la bébête ?

Question 4

Comment feriez-vous pour changer la quantité, le type ou les proportions des bébêtes présentes dans le champ ?

NB: ne perdez pas de temps avec les méthodes utilitaires de calcul de direction et de distance, qui sont dans une classe utilitaire. 
Ne perdez pas de temps avec la classe de lancement de programme « bebetes.LanceBebetes ». 
Ne prenez pas en considération (pour l’instant) les tests unitaires.

Les étapes suivantes apporteront des réponses basées sur les patrons de conception, afin de rendre le code plus évolutif (meilleure structuration du code).

 

Partie II - Patron de structure: décorateur

  Temps estimé: 60 minutes

Pour répondre à la Question 3, puisqu’il s’agit d’ajouts non fonctionnels, et plutôt que de faire beaucoup d’héritage (nombre de décorations x nombre de types de bébêtes), vous allez appliquer le patron Décorateur. Procéder en cinq étapes : 

Question 5

Créez un décorateur de Bebete qui n’ajoute rien mais qui ne modifie rien. Comme le décorateur devra se comporter comme une Bebete, votre IDE devrait vous aider en générant des méthodes pour vous. Cependant, la classe abstraite Bebete n’est peut-être pas assez détaillée (il pourrait manquer des méthodes pour permettre la substitution d’une Bebete par sa décoratrice).

Question 6

Essayez votre décorateur (vous ne devez pas voir de différence). Pour introduire une ou plusieurs bébêtes décorées, il vous faudra modifier la méthode fabriqueBebetes de la classe ChampDeBebetes.

Question 7

Dupliquez le test unitaire TestOrdre en changeant les bébêtes b1 et b2 par des décoratrices de b1 et b2. Vous devriez constater un problème lié à la méthode getChosesVues de PerceptionAble.

Pour exécuter un test unitaire dans Eclipse, cliquez bouton droit sur le test à exécuter, "Run as" ..., JUnit Test. Il faut avoir ajouté dans le "Build Path" la bibliothèque JUnit4 pour que le test compile !

Question 8

Après avoir corrigé la méthode getChosesVues de PerceptionAble, implanter deux décorateurs "concrets" : 

  1. Un qui ajoute (par décoration) un nom aux bébêtes et qui le dessine ;
  2. Un autre qui affiche un écho autour des bébêtes (cercle coloré qui s'agrandit à chaque pas de simulation).

Voir le résultat attendu à la fin de la partie II.

Partie III - Patron de création: Usine/Fabrique

   Temps estimé: 40 minutes

Nous appellerons écosystème un milieu capable de générer des bébêtes. Au moment de créer le champ de bébêtes, nous devrons préciser quel écosystème nous souhaitons "simuler". Nous considérerons 3 écosystèmes :  

  • La nuée (100% de bébêtes émergentes) 
  • L'aléatoire (100% de bébêtes hasards) 
  • Le mixte (x% de bébêtes hasards et (100-x)% de bébêtes émergentes) 

Ces trois écosystèmes seront trois fabriques. Une fabrique sera utilisée par ChampDeBebetes. Modifiez cette classe en conséquence, avec un impact notamment sur la méthode fabriqueBebetes. 

Question 9

Définir une interface BebeteFactory et implanter les 3 écosystèmes en tant que fabriques.

L'usine à utiliser est choisie lors de la construction du champ de bébêtes.

Partie IV - Fabrique de Fabriques

En pratique, le champs de bébêtes n'a pas besoin de connaître l'usine concrète qui est utilisée. Il devrait également être possible de changer d’écosystème en cours d’exécution et de régénérer la liste des bébêtes. Pour cela il faut utiliser une fabrique de fabriques.

Une fabrique de fabriques est une classe (EcosystemFactory) qui possède une méthode getEcosystem pour créer une BebeteFactory. L'utilisateur ne connaît pas la classe concrète utilisée. Le critère de construction de la fabrique peut être arbitraire (Random) ou peut dépendre d'un paramètre de la méthode getEcosystem.

Question 10

Créer la classe EcosystemFactory et sa méthode getEcosystem. Le choix de l'écosystème produit dépendra du choix fait par l'utilisateur dans une liste déroulante (JComboBox). Cette classe connaît toutes les fabriques concrètes disponibles et les offres à l'utilisateur. Lorsqu'une solution est choisie, le champs de bébêtes est modifié pour prendre en compte la nouvelle usine. Les bébêtes existantes sont détruites et de nouvelles bébêtes sont construites à partir de la nouvelle BebeteFactory. La classe ChampDeBebetes de doit jamais connaître le type concret utilisé !

Voir le résultat attendu à la fin de la partie IV.