:: Enseignements :: Master :: M1 :: 2015-2016 :: Programmation Orientée Objet - Design Patterns ::
[LOGO]

Ré-écrivons ls


Le but de ce TD est de comprendre le principe Open/Close et le design par interfaces.
On veut afficher les fichier présents dans des répertoires, un fichier est affiché ou non en fonction d'options passées sur la ligne de commande.
Voici des exemples d'utilisation du programme, par défaut si aucune option n'est fournie, le programme affiche tous les fichiers non cachés (un fichier caché commence par '.') dans le répertoire courant.
       java cmdline0.ListFile
     

Si l'on veut afficher le contenu de plusieurs répertoires, on peut les indiquer en argument. Par exemple,
       java cmdline0.ListFile folder1 folder2
     
affiche les fichiers (non cachés) des répertoires folder1 et folder2.
Si l'on veut aussi afficher les fichiers cachés, on peut utiliser l'option "-a".
       java cmdline0.ListFile -a
     

Si l'on veut afficher les fichiers qui vérifient une expression régulière, on peut utiliser l'option "-m". Par exemple,
       java cmdline0.ListFile -m ".*\.txt"
     
affiche les fichiers ".txt"
Bien sûr, les options sont composables.

Exercice 1 - Ligne de commande et liste de fichiers

Un stagiaire a écrit un prototype du programme, celui-ci est composé de deux classes.
  • Une classe CmdLine qui s'occupe de la gestion des options sur la ligne de commande.
  • Une classe ListFile qui possède un main et s'occupe de lister les fichiers en fonction des options de la ligne de commande récupérées en utilisant CmdLine.


  1. Expliquez le principe de fonctionnement de la classe CmdLine. Où est le problème de design ici ?
    Pour améliorer le design, l'idée consiste à demander à l'utilisateur d'enregistrer pour chaque option un code qui sera exécuté si l'option est sur la ligne de commande.
    Comment représenter un code que l'on va exécuter en Java ?
    Faire une représentation UML sous forme d'un diagramme de classes de la solution que vous voulez implanter.
    Faire un refactoring de CmdLine et changer le main de ListFile pour mettre en oeuvre ce nouveau design.
  2. Expliquer ce que fait la méthode list de ListFile.
    Pourquoi la signature de la méthode list ne devrait pas prendre de String en paramètre ?
    Faite les changements qui s'impose.
  3. Il va falloir maintenant ajouter la gestion des options qui sont suivies d'un paramètre, comme l'option "-m" dans notre exemple. On veut donc pouvoir gérer à la fois des options à zéro paramètre et des options à un paramètre.
    Quelle doit être l'API de CmdLine dans ce cas ?
    Rappel de Java: une fonction qui a zéro argument et renvoie void peut être typée par l'interface fonctionnelle java.lang.Runnable et une fonction à un paramètre peut être typée par java.util.function.Consumer.
    En non, on ne s'intéresse pas au cas où l'on peut gérer n paraamètres.
  4. Une fois l'API définie, passons à l'implantation.
    Comment faire pour en interne représenter à la fois des fonctions à zéro paramètre et à un paramètre de façon commune, de manière à pouvoir les stocker et les traiter avec le même code ?
    Indication 1: on peut utiliser un itérateur pour modéliser le fait que l'on va lire un paramètre supplémentaire ou pas.
    Indication 2: utiliser la délégation et pas l'héritage !
    Implanter le design retenu et ajouter la gestion de "-m" au main de ListFile.
  5. Notre travail est terminé sur CmdLine, on considère maintenant ce module comme fermé.
    Rappeler ce que fermé veut dire et quel est l'intérêt.
  6. L'implantation du main utilise une table de hachage dont les valeurs sont soient un booléen pour l'option -a soit un String/Pattern pour l'option -m, donc le type déclaré des valeurs pour la table de Hachage est Object, ce qui entraine un affreux cast.
    On souhaite résoudre ce problème en utilisant un objet correctement typé pour stocker la configuration plutôt qu'une table de hachage.
    On se propose d'utiliser une classe Configuration pour représenter la configuration du programme, les valeurs possibles pour les options -a et -m. Cette configuration sera changée dans le main lors du parsing des options de la ligne de commande.
              static class Configuration {
                boolean all;
                Pattern pattern;
              }
    	    

    Modifier le code du main pour que le résultat d'une configuration par la ligne de commande soit correctement typée et que les valeurs par défauts des différentes options soient facilement lisibles dans le code.
  7. En fait, on peut remarquer finalement que le traitement des fichiers cachés et le traitement de l'option "-m" sont juste des façons de filtrer suivant le nom du fichier, donc la méthode list devrait juste prendre en paramètre une fonction de filtrage. Celle-ci pourra elle même être créée en composant plusieurs fonctions de filtrage.
    Modifier le code de listFile et du main pour créer une configuration basée sur des fonctions de filtrage.