:: Enseignements :: ESIPE :: E4INFO :: 2014-2015 :: Programmation Orientée Objet - Design Patterns ::
[LOGO]

Refactoring



Le but de l'exercice suivant est de prendre un code existant et de le modifier. Avant de le modifier, il est souvent intéressant de modifier le code en introduisant un ou plusieurs design patterns qui vont nous aider à faire évoluer le code dans un second temps.
On appelle l'étape qui consiste à modifier un code existant sans introduire de nouvelles fonctionnalités mais uniquement à modifier un code existant pour le rendre plus clair et plus facilement modifiable, une étape de code refactoring.

Exercice 1 - Etre mis à l'index

Un de vos collègue a écrit un code permettant de creér un index de mots présents dans un fichier qui enregistre pour chaque mot la liste des occurences de celui-ci, sous la forme de couples, numéro de ligne, numéro de colonne.

Le code a été livré avec un main de test qui charge un fichier (la génèse) et construit un index des mots puis affiche la liste des occurences du mot "light".
		   Index index = new Index(Paths.get("td6/genesis.txt"));
		   System.out.println(index.getOccurences("light"));
		 

Le problème du code actuel et que l'index créé est gourmand en mémoire, par exemple, même si il existe une seule occurence d'un mot, le programme va créer un ArrayList pour stocker un seul objet Occurence. Il est possible de simplifier la structure de données en stockant un tableau d'entier long (long[]) pour chaque mot, un entier long (donc sur 64bits) étant la contaténation du numéro de ligne et du numéro de colonne chacun sur 32 bits. Pour garder la même interface (au sens générique du terme) pour la recherche, la méthode getOccurences, devra aussi retourner une liste d'Occurences qui sera créer à partir du tableau d'entiers long (en décodant les 64 bits en 2 mots de 32 bits).
Comme cette nouvelle implantation est moins gourmande en mémoire mais plus gourmande en temps processeur (il faut reconstruire la liste d'occurences à chaque appel de getOccurences), on souhaite que les deux implantations de l'index co-existent, sous les noms "regular index" et "tiny index".

  1. Quelles sont les refactorings à appliquer et les design patterns à introduire avant de créer la nouvelle implantation ?
    Dessiner le diagramme UML correspondant.
  2. Effectuer les refactorings sur le code.
  3. Ajouter le code de support du tiny index en plus du regular index.
  4. En fait, il est possible de compresser un peu plus la liste d'occurences, en utiliant un tableau d'entiers (int[]). Au lieu de stocker un offset de ligne et un offset de colonne, l'idée est de stocker un seul offset correspondant au nombre de caractères à partir du début du fichier (donc le fichier ne fera pas plus de 2Go).
    A partir de cet offset, pour retrouver le numéro de ligne et de colonne, on stockera dans une table annexe, l'offset de chaque début de ligne. En utilisant un algorihtme de dichotomie, Arrays.binarySearch en Java, il est possible de trouver l'index dans le table des débuts de ligne dont l'offset est inférieur à l'offset du mot courant. L'index nous donnera le numéro de la ligne, la soustraction entre l'offset du mot et l'offset de début de ligne, nous donnera le numéro de colonne.
    Quels sont les changements que nous devons effectuer pour prendre en compte ce nouvel encodage ?
  5. Effectuer le refactoring nécessaire permettant d'implanter le regular index et le tiny index avec le nouveau design.
  6. Si il vous reste un peu de temps, implanter le nouveau type d'index (compressed index).
Il n'y a pas de lecture pour préparer la scéance suivante car il s'agit de la scéance du TP noté !