IFT232_Exercices_Robots.doc

Le but de cette séance d'exercices est de vous préparer pour l'examen final. ....
classes et interfaces nécessaires pour réaliser le « Command design pattern ».

Part of the document


IFT232 Méthodes Orientées Objets Exercices VI Énoncé Le but de cette séance d'exercices est de vous préparer pour l'examen
final. Voici un exemple partiel d'examen. Vous auriez normalement 3 heures
pour le solutionner sur papier. Dans le cadre de cette séance d'exercices,
vous devez faire les implémentations complètes. Étude de cas : Robot Autonome Vous venez de découvrir dans le grenier de vos grands-parents, un robot de
la première génération des robots autonomes. Ces robots pouvaient mener
une vie presque autonome... à condition bien sûr de les programmer
correctement. Le vôtre est déjà programmé en Java, un vieux langage de
programmation certes, mais malgré tout pas si mal foutu. Plein d'espoir, vous commencez à examiner le code du programme, que vous
trouverez ci-dessous. Les classes principales sont Film, Lieu, Marchandise
et Robot. Les classes Film, Lieu, Marchandise représentent en fait des
structures de données passées en arguments aux actions primitives que peut
réaliser un robot. La classe Robot contient les actions primitives. Ces
actions primitives sont encodées sous forme de méthodes : voir(Film) ,
aller(Lieu) , dormir(Lieu, Date), acheter(Marchandise). Des scripts plus
complexes peuvent être aussi spécifiés à l'aide de méthode. La méthode
passerUneBonneSoiree() constitue un exemple d'une action complexe
correspondant è une séquence d'actions primitives. Un robot vieillit et les
actions primitives qu'il peut réaliser sont contraintes par son âge. Un
robot de moins de 13 ans est considéré comme un enfant. Un robot âgé entre
13 et 18 ans comme un adolescent. Un robot âgé de 18 ans et plus comme un
adulte. Après avoir examiné le code existant de près, vous êtes franchement déçu. A
preuve, toutes ces conditionnelles, ce n'est vraiment pas de la
programmation par objets... Le coeur vaillant et plein d'espoir vous
décidez de refactoriser le code afin de le rendre facilement modifiable
pour pouvoir ajouter de nouvelles fonctionnalités à votre robot, en
particulier,
. modifier son comportement en fonction de nouvelles catégories d'âge,
. implémenter de nouvelles actions primitives,
. implémenter la possibilité de réaliser de nouvelles commandes
complexes,
. augmenter son autonomie de décision... Voici les fragments principaux du programme de votre robot. /**
* LA classe Robot
*/
public class Robot {
private GregorianCalendar anniversaire_;
/**
* Méthodes statiques
*/ protected static Robot getRobot(int age) {
GregorianCalendar anniversaire = new GregorianCalendar();
anniversaire.add(GregorianCalendar.YEAR, 0 - age);
return new Robot(anniversaire);
}
public static Robot getEnfant() {return getRobot(5);}
public static Robot getAdolescent() {return getRobot(15);}
public static Robot getAdulte() { return getRobot(25); } /**
* CONSTRUCTEURS
*/ public Robot(GregorianCalendar naissance) {
setAnniversaire(naissance);
} /**
* ACCESSEURS
*/ public int getAge() { ... } public GregorianCalendar getAnniversaire() {return anniversaire_;}
public void setAnniversaire(GregorianCalendar newAnniversaire) {
anniversaire_ = newAnniversaire;
}
public boolean isEnfant() {return getAge() < 13;}
public boolean isAdolescent() {return (!isEnfant()) && getAge() < 18;}
public boolean isAdulte() { return getAge() > 17;} /**
* La méthode viellir() est invoquée à tous les ans à l'anniversaire du
robot;
*/
public void vieillir() {}
public boolean voir(Film unFilm) {
if (isEnfant())
return unFilm.getCategorie() == Film.GENERAL;
if (isAdolescent())
return unFilm.getCategorie() == Film.GENERAL
|| unFilm.getCategorie() == Film.RESTREINT;
if (isAdulte())
return true;
return false;
}
/**
* ACTIONS PRIMITIVES
*/ public boolean acheter(Marchandise objet) {
if (isEnfant())
return objet.isVenteLibre();
if (isAdolescent())
return objet.isVenteLibre();
if (isAdulte())
return true;
return false;
} public boolean aller(Lieu lieu) {
if (isEnfant())
return lieu.isAccesLibre();
if (isAdolescent())
return lieu.isAccesLibre();
if (isAdulte())
return true;
return false;
} public boolean dormir(Lieu lieu, Date heure) {
if (isEnfant())
return lieu.isAccesLibre() && heure.getHours() < 21;
if (isAdolescent())
return lieu.isAccesLibre() && heure.getHours() < 24;
if (isAdulte())
return true;
return false;
}
/**
* ACTIONS COMPLEXES
*/ public boolean passerUneBonneSoiree() {
if (isEnfant()) {
aller(new Lieu("CINEMA", true));
voir(new Film("Harry Potter", Film.GENERAL));
acheter(new Marchandise("Popcorn", true));
dormir(new Lieu("MAISON", true), new Date("21:00:00"));
}
if (isAdolescent()) {
aller(new Lieu("CINEMA", true));
voir(new Film("American Pie", Film.RESTREINT));
acheter(new Marchandise("Popcorn", true));
dormir(new Lieu("MAISON", true), new Date("23:00:00"));
}
if (isAdulte()) {
aller(new Lieu("CINEMA", true));
voir(new Film("Dernier Tango à Paris", Film.ADULTE));
aller(new Lieu("DISCOTHEQUE", false));
acheter(new Marchandise("Biere", false));
dormir(new Lieu("HOTEL", false), new Date("3:00:00"));
}
return true;
}
}
/**
* LA classe FILM
*/ public class Film {
public final static int GENERAL = 0;
public final static int RESTREINT = 12;
public final static int ADULTE = 17;
private java.lang.String titre_;
private int categorie_ = GENERAL;
public Film(String titre, int categorie) {
setTitre(titre);
setCategorie(categorie);
}
public int getCategorie() { return categorie_; }
public void setCategorie(int newCategorie) {categorie_ = newCategorie;
}
public java.lang.String getTitre() { return titre_; }
public void setTitre(java.lang.String newTitre) { titre_ = newTitre; }
} /**
* LA classe LIEU
*/
public class Lieu { private java.lang.String description_;
private boolean accesLibre_ = true;
public Lieu(String description, boolean categorie) {
setDescription(description);
setAccesLibre(categorie);
}
public java.lang.String getDescription() { return description_; }
public void setDescription(java.lang.String newDescription) {
description_ = newDescription;
}
public boolean isAccesLibre() { return accesLibre_; }
public void setAccesLibre(boolean newAccessLibre) {
accesLibre_ = newAccessLibre;
}
} /**
* LA classe Marchandise
*/ public class Marchandise {
private java.lang.String description_;
private boolean venteLibre_ = true;
public Marchandise(String description, boolean categorie) {
setDescription(description);
setVenteLibre(categorie);
}
public java.lang.String getDescription() { return description_;}
public void setDescription(java.lang.String newDescription) {
description_ = newDescription;
}
public boolean isVenteLibre() { return venteLibre_; }
public void setVenteLibre(boolean newVenteLibre) {
venteLibre_ = newVenteLibre;
}
} Première étape : Refactorisation du code existant Question 1 : Tests et JUnit (10 pts)
Avant de vous lancer corps et âmes dans la refactorisation de ce programme,
vous devez écrire quelques tests pour vous assurer que le comportement du
programme sera préservé. a) A l'aide de JUnit, définissez la classe TestRobot. b) Redéfinissez les méthodes permettant de gérer les fixtures. c) Implémentez 4 tests unitaires pour tester la méthode voir(Film) de la
classe Robot.
Question 2 : Refactorisation et poly morphisme (30 pts) Vous êtes maintenant prêt à refactoriser le programme afin de le rendre
facilement modifiable et d'y ajouter de nouvelles fonctionnalités, en
particulier,
. modifier son comportement en fonction de nouvelles catégories d'âge,
. implémenter de nouvelles actions primitives,
. implémenter la possibilité de réaliser de nouvelles commandes
complexes,
. augmenter son autonomie de décision... Refactoriser le programme de manière à faire disparaître toutes les
conditionnelles qu'il contient en les remplaçant par du polymorphisme. Question 3 : Vieillir (10 points)
Actuellement les étapes de la vie d'un robot se partage entre l'enfance,
l'adolescence et l'âge adulte. Vous désirez un découpage plus fin des
tranches de vie d'un robot, par exemple l'âge d'or, mais vous ne savez pas
encore exactement lesquelles. a) Implémenter les classes et les méthodes pour pouvoir le faire
facilement. Modifier l