:: Enseignements :: ESIPE :: E4INFO :: 2014-2015 :: Programmation Orientée Objet - Design Patterns ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Retour sur les convois |
Exercice 1 - Retours sur vos rendus ...
Exercice 2 - Fermeture
En y regardant de plus près, la méthode createConvoy écrite en début de semaine est en fait un FileParser, dont la seule "intelligence" est de connaître le format général des fichiers de description et d'appeler la factory reçue en argument.
Ce code peut et doit être fermé. faites-le.
Fermer ce code de parsing comme vous aviez fermé le code du serveur au td1-C.
Doit-on toujours renvoyer une liste de véhicules ?
Exemple: comment un collègue pourra faire des statistiques sur le ratio camion/auto sur les convois de l'année ?
Exercice 3 - Description des paramètres
Quand on reprend le code du td3-A, on se rend compte aussi que chaque "sous-factory" est responsable du parsing de ses paramètres.
Ce code est dupliqué. Cela entraîne des risques d'incohérence de format ou d'utilisation de convention différentes suivant les types de véhicules.
Par exemple, on veut éviter qu'un type de véhicule puisse supporter des arguments entre et pas les autres.
(si on avait pris l'option de laisser une chaîne de caractère unique pour tous les arguments, ce serait encore plus nécessaire,
pour éviter qu'il puisse y avoir des conventions différentes dans le format, avec par exemple un camion avec ses arguments séparés par des virgules
alors qu'une voiture a ses arguments séparés par des espaces).
on peut aussi imaginer qu'on veuille supporter ()sans modifier la factory!) un autre format de fichier de description, avec des ordres de paramètres différents.
Pour résoudre ce problème, l'objectif est de centraliser le code de parsing des paramètres.
Pour vous aider voilà le code d'initialisation que l'on souhaiterait écrire
(ainsi que le code de la classe
Arguments)
public static void main(String[] args) {
VehicleDecoder decoder = new VehicleDecoder();
decoder.register("truck", "color", "maxWeight");
decoder.register("moto", "color", "maxWeight");
decoder.register("car", "color", "maxWeight", "maxPersons");
VehicleFactory factory = new VehicleFactory();
factory.register("truck", (Arguments arguments) -> new Truck(arguments.getValue("color"), Integer.parseInt(arguments.getValue("maxWeight"))));
factory.register("moto", (Arguments arguments) -> new Moto(arguments.getValue("color")));
factory.register("car", (Arguments arguments) -> new Car(arguments.getValue("color"), Integer.parseInt(arguments.getValue("maxWeight")), Integer.parseInt(arguments.getValue("maxPersons"))));
...
Faites la conception et le schéma UML de la solution que vous proposez.
Quelques règles simples et universelles pour vous guider : une responsabilité par classe; être capable de nommer correctement vos classes; pas de duplication "inutile".
Rappel : la fonctionnalité de FileParser étant fermée, le code ne peut en aucun cas être modifié.
N'oubliez pas que différents types de véhicules supportent des listes de paramètres différentes.
Implémenter la solution retenue. N'hésitez pas à itérer sur votre conception si vous avez tombez sur une impasse !
Exercice 4 - Des paramètres typés ? (optionel, pour aller plus loin)
Avec Cette première solution, il reste deux "problèmes" :
- on aimerait repérer les erreurs au plus tôt, donc lors du parsing des paramètres, et pas uniquement dans la factory
- le code de conversion de type est dupliqué (string -> integer, mais oui!).
Comme on veut que les paramètres soient typés, lors de l'enregistrement d'un type de véhicule,
on va décrire en plus du nom du paramètre, son type, d'où les méthodes,
addString ou
addInteger
Après le parsing, les arguments extraits du fichier vont être stockés dans la classe
Arguments,
qui doit être modifiée pour extraire des arguments typés.
Un exemple de main qu'on veut pouvoir écrire :
public static void main(String[] args) {
VehicleDecoder decoder = new VehicleDecoder();
decoder.register("truck", new ParameterBuilder().addString("color").addInteger("maxWeight").toParameters());
decoder.register("moto", new ParameterBuilder().addString("color").addInteger("maxWeight").toParameters());
decoder.register("car", new ParameterBuilder().addString("color").addInteger("maxWeight").addInteger("maxPersons").toParameters());
VehicleFactory factory = new VehicleFactory();
factory.register("truck", arguments -> new Truck(arguments.getString("color"), arguments.getInteger("maxWeight")));
factory.register("moto", arguments -> new Moto(arguments.getString("color")));
factory.register("car", arguments -> new Car(arguments.getString("color"), arguments.getInteger("maxWeight"), arguments.getInteger("maxPersons")));
...
Quel design pattern est utilisé par la classe ParameterBuilder ?
Faites la conception et le schéma UML de la solution que vous proposez.
Implémenter la solution retenue.
Votre solution a-t-elle des limites ou des inconvénients ?
© Université de Marne-la-Vallée