- Cours: M2103 - support ici
- Enseignants: Marin Bougeret, Sébastien Gagné, Victor Poupet, Petru Valicov, Bruno Yun
- Le forum Piazza de ce cours pour poser vos questions
- Email pour une question d'ordre privée concernant le cours.
- Le sujet du TP en format .pdf téléchargeable et imprimable.
Avant de démarrer le TP, vérifiez que vous n'avez pas atteint votre quota d'espace de stockage autorisé :
- placez-vous dans votre
$HOME
et utilisez les commandes suivantes :du -sh
pour voir combien d'espace vous avez déjà utilisédu -sh *
pour voir combien d'espace vous avez déjà utilisé pour chaque fichier (sans fichiers cachés)du -sch .[!.]* *
pour voir combien d'espace vous avez déjà utilisé pour chaque fichier, y compris les fichiers cachés
- Supprimez les fichiers inutiles.
- Pour éviter des problèmes durant vos TPs d'informatique, vous devriez toujours garder 300-400 Mo d'espace libre.
On se propose ici de réaliser une application de gestion des étudiants dans un département informatique d'un IUT. L'objectif est de développer l'application de manière incrémentale en ajoutant les fonctionnalités demandées au fur et à mesure.
Il est vivement recommandé d'utiliser au maximum les fonctionnalités de l'IDE pour réaliser les tâches courantes (renommage d'attributs/méthodes, génération des différentes méthodes : constructeurs, setters, getters, etc.).
Important : Afin de garder une trace de la progression de votre application, il vous est demandé de travailler dans un package différent pour chaque exercice. Pour cela, vous copierez les classes écrites pour un exercice dans le package de l'exercice suivant à l'aide de l'IDE dans le panneau Project à gauche pour qu'il corrige automatiquement les déclarations de package. Garder une trace de progression pour chaque exercice vous permettra de mieux comparer votre travail pour chaque exercice et vous permettra également de mieux réviser plus tard.
Cliquez sur le lien ci-dessous pour faire votre fork privé du TP :
https://classroom.github.com/a/FY0Qks_1
- Sauf indication contraire, tous les attributs que vous allez déclarer dans ce TP (et dans les TPs qui suivent) doivent être privés (
private
). - A priori, la plupart des méthodes devraient être déclarées publiques (
public
). Vous pouvez tout de même déclarer et utiliser des méthodesprivate
du moment qu'elles vous sont utiles et que votre programme fonctionne correctement. - Pensez à respecter les conventions de nommage Java (vues en cours ou disponibles sur le site d'Oracle)
-
Créez et implémentez la classe
Etudiant
avec les attributs suivants : nom, prénom, date de naissance, adresse mail, adresse postale. Pour représenter les dates vous pouvez utiliser la classe statiqueLocalDate
du packagejava.time
. Voici un exemple de création d'une date :import java.time.LocalDate; class GestionEtudiants { public static void main(String args[]) { LocalDate maDate = LocalDate.of(2019, Month.FEBRUARY, 4); } }
Astuce : Si vous utilisez la classe
LocalDate
dans votre code sans l'importer, l'IDE vous proposera automatiquement de l'importer (placez le curseur sur le nom de la classe et appuyez sur Alt+↵ pour ajouter automatiquement la ligneimport java.time.LocalDate;
au début de votre fichier).Pour représenter les autres attributs vous pouvez utiliser le type
String
. Munissez également la classe d’un constructeur.Astuce : L'IDE peut générer automatiquement le code des méthodes usuelles pour une classe. Ainsi, après avoir déclaré les attributs de votre classe, faites un clic droit dans le code de la classe et sélectionnez «Generate...» (ou Alt+Insert) puis choisissez «Constructor». Sélectionnez les attributs que vous souhaitez passer directement en argument au constructeur (ici tous) et validez. Vous pouvez évidemment modifier par la suite le constructeur ainsi généré.
-
Créez la méthode
toString()
(qui renvoie un objet de typeString
) générant un texte de présentation des informations concernant l'objetEtudiant
.Attention : cette méthode n’affiche rien, elle se contente de produire une chaîne de caractères. Ce à quoi sert ce texte (par ex. à être affiché à l’écran, ou être écrit dans un fichier) dépend de l’utilisation de la méthode.
-
Ajoutez une fonction
setNom(...)
qui permet de changer le nom et le prénom d'un objet de typeEtudiant
. -
Vérifiez votre solution dans le programme principal (la classe
GestionEtudiants
) en instanciant dans la méthodemain(...)
une variablelolo
de typeEtudiant
et en affichant ses informations.Astuce : L'IDE possède des raccourcis pour les morceaux de codes fréquemment utilisés. Par exemple, pour faire un affichage à la console avec
System.out.println()
, tapez «sout
» à l'endroit où vous souhaitez insérer l'instruction la fonction et appuyez sur la touche ↹ (tabulation) pour que «sout
» soit remplacé par la déclaration complète (System.out.println()
). Vous pouvez voir la liste des raccourcis disponibles à tout moment en appuyant sur Ctrl+J (les raccourcis disponibles dépendent du contexte, par exemple si vous êtes en train d'écrire une méthode, directement à la racine d'une classe, etc.). -
Créez une nouvelle variable
toto
de typeEtudiant
construite avec exactement les mêmes paramètres quelolo
. Comparez les deux variables avec l'opérateur==
. Que constatez-vous ? -
Modifiez votre programme pour faire en sorte que
toto
fasse référence àlolo
. Vérifiez qu'une modification des attributs detoto
se répercute bien surlolo
. -
Créez une classe
Departement
qui aura comme attributs une spécialité, une adresse et un tableau d'étudiants inscrits géré sous forme de liste. Pour déclarer une telle liste vous pouvez utiliser la classeArrayList
du packagejava.util
(voir un exemple dans le cours). Munissez la classe d'un constructeur, qui prend comme paramètre un intitulé et une adresse. Définissez la méthodetoString()
dansDepartement
avec un texte qui liste l'ensemble des étudiants du département.Indication : Pensez à utiliser les fonctionnalités de l'IDE pour importer la classe
ArrayList
et pour générer le constructeur et la méthodetoString
. -
Ajoutez une méthode
inscrire(...)
dans la classeDepartement
qui prend en paramètre un étudiant et l'ajoute aux étudiants inscrits du département. -
Ajoutez une méthode
desinscrire(...)
qui supprime un étudiant passé en paramètre de la liste des étudiants inscrits. -
Vérifiez le bon fonctionnement de votre application dans la classe principale en créant un département
monDepInfo
et en y inscrivant quatre étudiants (donttoto
etlolo
définis précédemment). Désinscrivez ensuitetoto
du département. Que constatez-vous ?
Rappel : Pour préserver le code écrit dans l'exercice précédent copiez l'ensemble des classes du package
fr.umontpellier.iut.exo1
dans le package fr.umontpellier.iut.exo2
en utilisant les outils de refactoring de l'IDE.
Pour ce faire : clic droit sur le nom de la classe → Refactor → Copy
On souhaite étoffer le modèle objet conçu auparavant en y incluant les aspects pédagogiques du département. Pour cela on vous demande de gérer les matières, les enseignants et les notes.
-
Une
Matiere
est définie par un intitulé, un coefficient (une valeur réelle qui pourra servir pour le calcul d'une moyenne) et unProfesseur
responsable (une classe avec des attributs nom et prénom). Créez la classe correspondante avec un constructeur adéquat. Ajoutez dansMatiere
une méthode accesseurgetCoefficient()
qui retourne le coefficient. -
Une
Note
est définie par une matière et par un nombre réel (qui représente la valeur de la note). Déclarez la classe correspondante et ajoutez des méthodes accesseurs pour chacun des attributs. -
Ajoutez à la classe
Etudiant
un attribut correspondant à la liste de ses notes et une méthodenoter(...)
qui prend en paramètre une matière et une valeur réelle, crée un objet de typeNote
et l'ajoute à la liste des notes de l'étudiant. -
Sans toucher au code des autres classes, ajoutez à la classe
Etudiant
une méthodecalculerMoyenne()
qui permet de calculer la moyenne des notes de l'étudiant. Pensez à ajouter des tests unitaires pour vérifier le bon fonctionnement de cette fonction. Pour créer une classe de tests unitaires, placez-vous dans la classe que vous souhaitez tester et :- appuyez sur Alt+Insert (ou bien faites un clic droit sur le nom de la classe → Generate)
- Choisissez Test...
- dans l'onglet Testing library vous choisirez l'option JUnit 5
- donnez un nom approprié à votre classe de tests unitaires (par ex.
EtudiantTest
) et cliquez sur Ok.
Comme pour le TP précédent, la classe de tests générée sera automatiquement placée dans le même package que la classe testée et dans le répertoire correspondant aux tests. Pour écrire vos tests, vous pouvez vous inspirer des exemples vues dans le TP précédent.
-
Vérifiez que votre programme fonctionne bien dans la classe principale.
-
Construisez le diagramme de classes correspondant au programme Java que vous avez écrit. Vous pouvez le faire sur papier ou en utilisant un logiciel de modélisation.
Observez que la classe Etudiant
a un constructeur avec 4 paramètres. Bien entendu, le nombre de paramètres risque
de croître car beaucoup d'autres attributs sont susceptibles d'être ajoutés à la classe Etudiant
.
Observez aussi que lorsqu'on construit une instance d'Etudiant
il est facile de se tromper dans l'ordre des paramètres
du constructeur. Heureusement que l'IDE vous aide en vous suggérant cette ordre lorsque vous programmez...
De plus, les valeurs de certains attributs peuvent être inconnues au moment de la construction de l'objet : l'adresse de l'étudiant n'est pas encore connue car l'attribution des logements universitaires par les organismes correspondants n'a pas encore eu lieu; l'adresse mail étudiante n'est pas encore active au moment de l'inscription de l'étudiant, etc. Plusieurs solutions peuvent être envisagées :
-
Une solution est de définir plusieurs constructeurs avec différents paramètres et de les faire collaborer (voir exemples en cours). Ainsi l'utilisateur pourra choisir le constructeur qui lui convient. C’est ce qu’on appelle une construction télescopique.
Créez une nouvelle classe
EtudiantTelescopique
(en copiant les attributs de la classeEtudiant
de l'exercice 2) et modifiez-la afin de pouvoir instancier les étudiants de différentes manières :- en indiquant uniquement le nom et le prénom
- en indiquant uniquement le nom, le prénom et la date de naissance
- en indiquant uniquement le nom, le prénom et le mail
Vérifiez votre programme dans la classe principale.
-
Avec cette approche, est-il possible d'ajouter un constructeur supplémentaire afin d'indiquer uniquement le nom, le prénom et l'adresse ? Pourquoi ?
-
Une autre solution serait de suivre le modèle Java Beans, en proposant un seul constructeur minimal et en fournissant des méthodes modifieurs (setters) pour chaque attribut de la classe. Créez une telle classe appelée
EtudiantJavaBeans
. Voici comment se fera alors la construction des objets de ce type :class GestionEtudiants { public static void main(String args[]) { EtudiantJavaBeans toto = new EtudiantJavaBeans(); toto.setNom("Dupont"); toto.setDateDeNaissance(LocalDate.of(2000, Month.JANUARY, 28)); /* ... */ toto.setAdresse("1, av. des Champs-Elysées, 75008 Paris"); } }
-
Comparez cette solution avec celle de la classe
EtudiantTelescopique
. Quels sont les avantages et les inconvénients ? -
Finalement, on vous demande de développer une solution en combinant les bonnes idées des deux versions précédentes. Voici comment on voudrait pouvoir créer des étudiants dans la classe principale :
class GestionEtudiants { public static void main(String args[]) { Etudiant lolo = new EtudiantBuilder() .ajouterNom("Dupont") .ajouterPrenom("Philippe") .ajouterDateNaissance(LocalDate.of(2000, Month.JANUARY, 28)) .ajouterMail("dupont@etu.umontpellier.fr") .ajouterAdresse("1, av. des Champs-Elysées, 75008 Paris") .build(); } }
Remarquez qu'il n'y a qu'un seul symbole
;
dans le programme ci-dessus. Autrement dit, l'instanciation de l'objet se fait avec une seule instruction, qui a été écrite sur plusieurs lignes pour plus de lisibilité.Ajoutez la classe
EtudiantBuilder
à votre application pour que l'instruction ci-dessus fonctionne.
Pour aller plus loin : Vous noterez que la classe EtudiantBuilder
sert uniquement à instancier des objets Etudiant
de manière
"organisée" et lisible. Le problème est qu'il est toujours possible d'instancier un objet de type Etudiant
sans utiliser le builder que vous avez écrit...
C'est pour cela qu'il est possible d'améliorer la dernière solution en déclarant la classe EtudiantBuilder
comme classe interne statique de la classe Etudiant
et de rendre private
le constructeur de la classe Etudiant
.
Ainsi la construction pourra se faire exclusivement à travers le builder et celui-ci servira uniquement à la construction
des objets de type Etudiant
, car c'est son seul rôle. Pour plus de détails et explications, voir le modèle de conception Builder.
Une explication approfondie est donnée dans Effective Java, J. Blosch, (2nd or 3rd edition).