TP Annuaire

a partir d'exercices propose par  Philippe Genoud, Xavier Girod Philippe.Genoud@imag.fr.

Objectifs :

  • Aborder au travers d'une application simple les structures de données de l'API JAVA 2 ( interfaces et classes Map, List, ArrayList, HashMap, TreeMap, Set du package java.util) ainsi que les itérateurs.
  • Utiliser les nouvelles fonctionnalités de Java 5 concernant les classe génériques et les énumérations

On souhaite réaliser une application de gestion d'un annuaire téléphonique qui permet d'associer à une personne un ou plusieurs numéros de téléphone.

Cette application s'articulera autour des classes et interfaces suivante:

  • Personne: classe représentant une personne définie par un nom, un prénom et une civilité (M., Mlle, Mme).
  • NumTel : classe représentant un numéro de téléphone, défini par le numéro proprement dit et un code qui indique la nature du numéro (numéro de portable, numéro de poste fixe professionnel, numéro de poste fixe à domicile, numéro de Fax).
  • IListeNumTel: interface définissant les fonctionnalités d'une liste de numéros de téléphone.
  • IAnnuaire: interface définissant les fonctionnalité d'un annuaire téléphonique, c'est à dire d'un ensemble d'associations <p,ln> avec p une Personne et ln une ListeNumTel.

Votre travail consiste à réaliser et tester différentes implémentations des interfaces IListeNumTel et IAnnuaire en utilisant les services de différentes classes du package java.util.


Le source de ces différentes classes et interfaces vous est fourni. Téléchargez et décompressez sur votre compte le fichier annuaire.zip qui contient les fichiers suivants :

    • NumTel.java : source de la classe représentant un numéro de téléphone,
    • Personne.java : sources de la classe représentant une personne,
    • IListeNumTel.java : source de l'interface décrivant les services offert par une liste de numéro de téléphones,
    • IAnnuaire.java : source de l'interface définissant les services offerts par un annuaire et qui sera utilisée dans la deuxième partie de ce TD.
    • ListeNumTelTest.java: source d'un programme interactif pour le test des implémentations de IListeNumtel,
    • LectureClavier.java : classe pour les lectures de valeurs au clavier,
    • ImpListeNumtel.class : le bytecode d'une implémentation de l'interface IListeNumtel qui vous permettra d'expérimenter avec le programme ListeNumTelTest.

1ère partie : Première implémentantion de l'interface IListeNumTel

L'interface IListeNumTel définit une liste des numéros de téléphone pour une personne. Une liste de numéros n'est jamais vide, elle contient toujours au moins un numéro.

La spécification des méthodes publiques de l'interface IListeNumTel est donnée dans le tableau suivant:

Liste des méthodes
 boolean ajouter(int index, NumTel num)
          ajoute un numéro à une position donnée dans la liste, sans effet si le numéro est déjà présent dans la liste.
 boolean ajouterDebut(NumTel num)
          ajoute un numéro au début de la liste, sans effet si le numéro est déjà présent dans la liste.
 boolean ajouterFin(NumTel num)
          ajoute un numéro à la fin de la liste, sans effet si le numéro est déjà présent dans la liste.
 boolean contientNumero(int num)
          Teste la présence d'un numéro dans la liste.
 java.util.Iterator iterator()
          Renvoie un itérateur sur les numéros de téléphone contenus dans la liste.
 int nbNumeros()
          retourne le nombre de numéros de la liste (>=1).
 NumTel numero(int index)
          retourne le ième numéro de la liste.
 NumTel premierNumero()
          retourne le premier numéro de la liste (il existe forcément)
 boolean retirer(int num)
          Enlève un numéro de la liste, cette opération n'est possible que si la liste contient au moins deux numéros (nbNumero()>1).
 java.lang.String toString()
          Retourne dans une chaîne de caractères la séquence des numéros contenu dans cette liste.

Votre premier travail consiste à réaliser et tester une implémentation de cette interface. Pour réaliser cette implémentation vous vous appuyerez sur les services de java.util.List pour stocker les différents numéros de téléphone.

  1. A votre avis pourquoi la classe ListeNumtel délègue-t-elle la gestion de la liste des numéros de téléphone à un objet java.util.List plutôt que d'hériter d'une implémentation de java.util.List (par exemple java.util.ArrayList) ?
  2. Ecrire et compiler votre classe ListeNumTel implémentation de l'interface IListeNumtel
  3. Tester votre implémentation de l'interface ListeNumtel avec le programme ListeNumTelTest. Pour cela vous remplacerer dans la code de ListeNumTelTest les références à ImpListeNumtel par des références à votre classe ListeNumTel.

2ème partie : Réalisation de la classe Annuaire

Un annuaire permet d'associer à une personne une liste de numéros de téléphone. Les méthodes de l'interface IAnnuaire sont les suivantes 

Liste des Méthodes
 void afficher()
          affiche l'intégralité de l'annuaire, sous la forme d'une personne par ligne suivie de ses numéros de téléphone.
 boolean ajouterEntree(Personne p, IListeNumTel nums)
          ajoute une nouvelle entrée dans l'annuaire.
 void ajouterNumeroDebut(Personne p, NumTel n)
          ajoute un numero au début de la liste des numéros d'une personne.
 void ajouterNumeroFin(Personne p, NumTel n)
          ajoute un numero à la fin de la liste des numéros d'une personne.
 ListeNumTel numeros(Personne p)
          retourne les numéros si la personne est absente retourne null
 java.util.Iterator personnes()
          renvoie un iterateur sur l'ensemble des personnes contenues dans l'annuaire
 NumTel premierNumero(Personne p)
          retourne le premier numéro d'une personne, si la personne n'est pas dans l'annuaire retourne null.
 void supprimer(Personne p)
          supprime une personne de l'annuaire.
 void supprimer(Personne p, int n)
          supprime un numero donné pour une personne.
 java.lang.String toString()
          retourne une chaîne représentant l'intégralité de l'annuaire.

Exercice 1 :

a) Réaliser une classe Annuaire implémentant l'interface IAnnuaire.

On utilisera comme structure de données pour l'annuaire une table associative (interface  Map) : la personne jouant le rôle de clé et la liste des numéros de téléphone étant la valeur associée à cette clé (on prendra une HashMap comme implémentation). Dans un premier temps on se contentera d'écrire une implémentation complète uniquement pour les méthodes ajouterEntree(Personne, ListeNumTel),personnes(), afficher() et numeros() de la classe Annuaire.

b) Tester ces méthodes avec le petit programme principal suivant qui :

  • crée un annuaire vide,
  • ajoute une entrée pour une personne de nom DURAND, prénom Sophie, Civilité Mlle. avec comme numéro 151171
  • ajoute une entrée pour une personne de nom DUPONT, prénom Jean, Civilité M. avec comme numéro 151171
  • ajoute une entrée pour une personne de nom DUSCHMOL, prénom Louis, Civilité M. avec comme numéro 146761
  • ajoute une entrée pour une personne de nom AARGH, prénom Robert, Civilité M. avec comme numéro 140361
  • affiche le contenu de l'annuaire.
  • effectue une recherche des numéros de la personne Sophie DURAND et une recherche des numéros de Jean DUPONT
  public static void main(String[] args) {

// crée un annuaire vide
IAnnuaire an = new Annuaire();

// ajoute deux personnes à l'annuaire
Personne p1 = new Personne(Personne.MLLE,"DURAND","Sophie");
an.ajouterEntree(p1,new ListeNumTel(new NumTel(151171,'D')));

an.ajouterEntree(new Personne(Personne.MR,"DUPONT","Jean"),
new ListeNumTel(new NumTel(151170,'P')));

an.ajouterEntree(new Personne(Personne.MR,"DUSCHMOL", "Louis"),
new ListeNumTel(new NumTel(146761,'P')));

an.ajouterEntree(new Personne(Personne.MR,"AARGHH", "Robert"),
new ListeNumTel(new NumTel(140361,'P')));


// imprime l'annuaire
System.out.println("------------------------------");
System.out.println(an);
System.out.println("------------------------------");

// Recherche des numéros de Sophie DURAND
System.out.println("numeros de " + p1);
System.out.println(an.numeros(p1));

// Recherche des numéros de Jean DUPONT
Personne p2 = new Personne(Personne.MR,"DUPONT","Jean");
System.out.println("numeros de " + p2);
System.out.println(an.numeros(p2));
}

Constatez que la recherche du numéro pour Jean DUPONT a échoué alors qu'elle a réussi pour Sophie DURAND. Quelle explication donnez vous à cela ?

c) Modifiez la classe Personne de manière à corriger les erreurs détectées précédemment.

Exercice 2 :

On voudrait que l'itérateur fournissant les différentes personnes enregistrées dans l'annuaire permette d'obtenir celles-ci selon l'ordre alphabétique, ce qui n'est pas garanti par une HashMap. Pour cela il vaudrait mieux utiliser comme implémentation de l'annuaire un objet instance de la classe TreeMap.

  1. Dans votre implémentation de l'annuaire remplacez HashMap par TreeMap
  2. Recompilez votre application et exécutez. Quel problème cela pose-t'il ? Quelle doit être la propriété de la classe Personne ?
  3. Faites les modifications nécessaires, refaites le test précédent et constatez les modifications lors de l'affichage de l'annuaire.

Exercice 3:

Ecrivez l'implémentation complète de la classe Annuaire et un programme de test de cette classe.

Exercice 4 :

On veut ajouter la méthode suivante à l'annuaire:

   /** 
* donne l'ensemble de toutes les personnes de l'annuaire dont le nom
* débute par une chaîne donnée.
* @param s1 la chaine pour la recherche
* @return l'ensemble des personnes de l'annuaire dont le nom débute
* par s1
*/
public Set entreesPourChaine(String s1)

Réaliser cette évolution et tester cette nouvelle méthode. (Indication : avant d'écrire ce code examinez attentivement toutes les méthodes de TreeMap)

3ème partie : Utilisation de Enum

Exercice: La civilité des personnes est codée par un entier. Modifier votre application, afin d'utiliser un type enuméré pour représenter l'attribut de civilité


4ème partie : Sauvegarde/recharger un annuaire


On veut maintenant pouvoir saugarder un annuaire sous une forme ou une autre et on veut pouvoir charger un annuaire "existant". Pour cela plusieurs solutions :

  • fichier binaire
  • fichier texte
  • sérialisation de l'annuaire
Inspirez vous de Agenda.jar en adaptant vos classes des exercice Annuaire

compléter le projet en implémentant les méthodes :
    /**
* enregistrer un Annauire
*/
public void sauvegarderAnnuaire(String sauvegarde)
{

}


public void chargerAnnauire(String fichierAnnuaire)
{

}

dans chacune des classes "AgendaTelBin" , "AgendaTelTxt" , "AgendaTelSerialisable" , "AgendaTelProperties" , "AgendaTelPropertiesXML" et commenter l'intéret et les défauts de chacune des solutions.

Comments