:: Enseignements :: ESIPE :: E4INFO :: 2013-2014 :: Programmation Orientée Objet - Design Pattern ::
[LOGO]

Refactor X


Le but de ce TD est d'analyser un code existant puis dans un second temps, de refactoriser le code pour l'améliorer.
Un programme écrit par un stagiaire permet d'effectuer des mouvements financiers sur des comptes et d'afficher une sortie indiquant le solde de chaque compte ainsi que les dernières opérations financières effectuées.
Le programme ne faisant pas exactement ce qui est demandé et ne respectant pas les bonnes pratiques de programmation, on vous propose dans un premier temps d'analyser le programme et dans un second temps, d'efectuer des transformations sur le code de celui-ci en vu de le rendre correct et acceptable.

accounts.txt contient une liste de comptes sous forme d'un triplet (numéro_du_compte prénom_et_nom__du_possesseur_du compte solde) Les valeurs numériques sont des entiers long et le nom et le prénom des chaines de caractères utilisant l'encodage US-ASCII.
records.txt est une liste de mouvements financiers sous forme d'un triplet (somme_d'argent compte1 compte2) qui indique qu'il faut transférer la somme d'argent (entier long) du compte1 au compte2.
On cherche à appliquer les mouvements financiers du fichier records.txt sur les comptes décrits dans accounts.txt et de ressortir un état de chaque compte indiquant le solde de celui-ci ainsi que les 5 dernières opérations de transfert d'argent (vers le compte ou à partir de ce compte).
process-out.txt correspond précisément à la sortie attendu du programme, celui-ci liste les utilisateurs dans le même ordre que account.txt et pour chaque utilisateur affiche son prénom et nom, le solde de son compte ainsi que les 5 dernières opérations effectuées sur ce compte.

Rappel, ouvrir et lire un fichier texte ligne à ligne en Java se fait de la façon suivante :
    Path usersPath = Paths.get("users.txt");
    Charset usAscii = StandardCharsets.US_ASCII;
    try(BufferedReader reader = Files.newBufferedReader(usersPath, usAscii)) {
      String line;
      while ((line = reader.readLine()) != null) {
         // line is a line without '/n' at the end
      }
    }  // implicitly call close() freeing file resources 
    

Exercice 1 - UML to the rescue

Dans le but de comprendre le programme existant, on vous demande de faire une diagramme de classe UML correspondant aux fichiers Java

Exercice 2 - Refactor


  1. Utiliser le principe "une classe, une responsabilité" pour indiquer la responsabilité des classes AccountDetails, LoadFile et Record.
  2. Que pouvez vous en déduire à propos de la classe LoadFile ?
  3. Expliquer quel est le problème du constructeur de LoadFile.
    Expliquer quel est le problème de la signature de la méthode LoadFile.loadRecords().
    Expliquer quel est le problème d'avoir toutes les méthodes de LoadFile déclarées public ?
    Expliquer quel est le problème de la gestion des exceptions dans le code de la méthode main de la classe LoadFile.
  4. Dans un premier temps, on peut noter que LoadFile.readFile et LoadFile.loadRecords ont une grosse partie de code commun.
    Ecrire une méthode statique parsequi sera utilisée par readFile et loadRecords pour partager le code commun.
  5. Faire en sorte que la méthode parse gère l'ouverture et la fermeture des fichiers.
    Changer le code pour que la classe LoadFile n'ait plus de champs et ne déclare que des méthodes statiques.
    Quel est l'avantage de faire se refactoring ?
  6. On remarque que le code de fixBalance oblige à rechercher plusieurs fois l'association entre un id et l'AccountDetails associé.
    Il serait plus judicieux de faire cette opération une unique fois, à la création des instances de la classe Record.
    Modifier les classes LoadFile et Record en conséquence.
  7. A quoi servent les méthodes getSumTransfer et setSumTransfer dans la classe Record ?
    Modifier la classe Record en conséquence.
  8. Les méthodes LoadFile.fixBalance et LoadFile.fixBalance2 ne semblent pas placées dans la bonne classe. Où devraient-elles être déclarées ?
    Faire les changements correspondants dans le code.
  9. Les codes de fixBalance et fixBalance2 sont quasi identiques, comment n'avoir qu'un seul code ?
    De plus, expliquer pourquoi il n'est pas nécessaire de stocker les Record dans une liste intermédiaire.
    Faite les transformations qui s'imposent.
  10. Le champ AccountDetails.listOfLastRecords n'utilise pas la bonne structure de donnée.
    Expliquer pourquoi ?
    Quelle doit être la bonne structure de donnée ?
    Quel est son nom en Java ?
    Modifier le code de AccountDetails en conséquence.
  11. Modifier la Map qui stocke les AccountDetails pour que l'ordre de parcours de la Map soit le même que l'ordre d'insertion.
  12. Nous allons, modifier le nom des variables locales, des constantes, etc. pour respecter la convention de code Java.
    Quelles sont tous les identificateurs qui doivent être changés ?
    Faite les changements qui s'imposent dans le code.
  13. Corriger les derniers problèmes qui trainent et débugger le code pour avoir la même sortie que le fichier process-out.txt.