:: Enseignements :: Licence :: L3 :: 2013-2014 :: Programmation Objet avec Java ::
|
TP noté 2 - Licence 3
|
Rappel: vous devez utiliser eclipse-lambda, configurer le JRE pour qu'il pointe
sur /usr/local/apps/Java8 et le compilateur pour utiliser la version 1.8.
Enfin, vous devez configurer le workspace d'Eclipse (File > Switch WorkSpace) pour
qu'il corresponde au répertoire EXAM que vous avez dans le home
de votre session de TP noté.
Attention, ce TP est corrigé pour partie de façon automatique! Il est donc très important
que le nom des classes et le nom des méthodes que l'on vous demande soit respecté.
Exercice 1 - Y'a pas marqué la poste, là !
On souhaite modéliser le fonctionnement d'un bureau de poste
qui permet de délivrer des messages à différents buildings d'une ville.
Le fonctionnement est le suivant: lorsque l'on cherche à envoyer
un message (post), on indique un identifiant (identifier)
qui correspond au nom du building (au moins dans un premier temps).
La poste délivre (deliver) le message à tous les buildings
(on verra que l'on peut améliorer l'algorithme plus tard)
et chaque building regarde si le message lui est destiné,
en comparant l'identifiant avec son nom. Si le nom
est le même, le message est stocké dans la boite de réception
(mailbox) du building.
L'ensemble des classes à écrire devra être déclaré dans le
package fr.umlv.tpnote2.
-
Écrire une classe CityBuilding qui modélise un building
ayant un nom non nul et qui ne change pas.
En aucun cas, le nom du building ne doit être connu par
un code extérieur à la classe.
-
Écrire une méthode d'affichage telle que le code suivant fonctionne
CityBuilding building = new CityBuilding("foo");
System.out.println(building); // affiche Building foo
-
Écrire une classe PostOffice modélisant un bureau de poste
et sa méthode createCityBuilding prenant le nom du building
en paramètre.
Comme un bureau de poste doit connaitre l'ensemble des buildings pour pouvoir
distribuer les messages, au lieu de permettre la création d'un building
directement, on va changer le code de CityBulding pour
obliger quiconque voulant créer un CityBulding à passer
par la méthode createCityBuilding de la classe
PostOffice.
Le code suivant ne devra donc plus compiler,
CityBuilding building = new CityBuilding("foo");
et être remplacé par
PostOffice postOffice = new PostOffice();
CityBuilding building = postOfice.createCityBuilding("foo");
-
Écrire la méthode post dans PostOffice
qui prend un identifiant et un message (deux chaines de caractères non nulles)
et qui délivre le message à l'ensemble des buildings créés aux préalables
en appelant createCityBuilding.
On vous demande pour cela d'écrire une méthode deliver dans la classe
CityBuilding. Cette méthode ne doit pas être accessible par
une classe hors du package fr.umlv.tpnote2.
Dans la méthode deliver, si l'identifiant correspond au nom du
CityBuilding, on vous demande dans un premier temps d'afficher
le message sur la sortie standard (pour tester).
Écrire de plus un main de test dans la classe Main.
-
Modifier deliver pour stocker les messages dans une boîte
de réception (mailbox). Utiliser pour cela une implantation
de l'interface Deque. De plus, pour que les messages soient
accessibles depuis n'importe quelle classe, écrivez un getter
pour accéder à la mailbox.
Attention à la signature du getter.
-
Faire en sorte que si un message n'est pas destiné à un building,
celui-ci le signale lors de l'appel à la méthode deliver.
Dans le cas où tous les buildings refusent le message, post
devra afficher que le message n'a pas été délivré.
-
On souhaite maintenant modéliser des maisons individuelles.
Contrairement aux CityBuilding les House sont identifiées
par le nom des propriétaires et celui-ci peut changer au cours du temps.
De plus, une maison peut aussi être inoccupée.
Écrire une classe House et une méthode setFamilyName
qui permet d'indiquer qu'une famille avec un nom vit dans la maison
(il est possible de spécifier un nom nul si personne ne vit dans la maison).
Écrire également sa méthode d'affichage de telle sorte que le code suivant fonctionne.
House house = new House();
house.setFamily("McDonald");
System.out.println(house); // McDonald's house
house.setFamily(null);
System.out.println(house); // empty house
-
On souhaite maintenant que les House puissent aussi recevoir du courrier.
Pour cela, créer une méthode createHouse sans paramètre
dans PostOffice.
Modifier le code de post pour que l'on puisse envoyer des messages
aussi bien aux CityBuilding qu'aux maisons.
Le code suivant devra donc fonctionner.
PostOffice postOffice = new PostOffice();
House house = postOfice.createHouse();
house.setFamily("McDonald");
postOffice.post("McDonald", "hello Mc");
System.out.println(house.getMailbox()); // [hello Mc]
house.setFamily("null");
postOffice.post("McDonald", "hello Mc"); // message not delivered !
Attention, vous devez implanter post de façon objet !
-
Modifier votre implantation pour que, si l'on post un
message avec l'identifiant citybroadcast, celui-ci soit délivré dans
toutes les mailbox des CityBuilding.
-
On veut améliorer l'algorithme de distribution des messages
mais toujours sans que le bureau de poste sache si un building ou une maison
va répondre à un message.
L'idée est la suivante, si deliver répond qu'un message est a été délivré
alors on enregistre dans un cache que le building (ou la maison) est capable
de comprendre l'identifiant et au prochain post, au lieu d'envoyer le message
à toutes les buildings (et maisons), on essaiera d'envoyer le message en premier
à ce building. Dans le cas où le building (ou la maison) répondrait par la négative
(par exemple si la famille a déménagé pour une maison, il faudra invalider
l'entrée dans le cache.
Implanter l'algorithme décrit ci-dessus en sachant qu'une HashMap fait un
très bon cache et qu'il faut faire attention aux messages de broadcast.
-
Lorsque une nouvelle famille arrive dans une maison, (avec setFamily),
s'il y a des messages dans la mailbox, ceux-ci doivent être
renvoyés automatiquement au bureau de post pour être re-postés vers la nouvelle
maison occupée par cette famille.
PostOffice postOffice = new PostOffice();
House house = postOfice.createHouse();
house.setFamily("McDonald");
postOffice.post("McDonald", "hello Mc");
House newHouse = postOfice.createHouse();
newHouse.setFamily("McDonald");
house.setFamily(null); // les MacDonald ont déménagé
System.out.println(newHouse.getMailbox()); // [hello Mc]
-
On souhaite rendre le système un peu plus flexible. L'idée est qu'au lieu
d'envoyer des messages sous forme de chaines de caractères, on va pouvoir
envoyer des commandes (Command) qui seront exécutées
par les buildings (et/ou maisons) ayant reçu ces commandes
(donc pas de stockage dans la mailbox dans ce cas).
Une commande est une fonction qui prend en paramètre le building
(ou la maison) ayant reçu la commande.
Le code suivant devra alors fonctionner
PostOffice postOffice = new PostOffice();
CityBuilding kino = postOfice.createCityBuilding("kino");
postOffice.postCommand("kino", building -> System.out.println("hello from " + building)); // hello from kino
De plus, la méthode post devra être ré-écrite pour utiliser postCommand.
© Université de Marne-la-Vallée