- Support de cours
- Enseignants: Malo Gasquet, Sophie Nabitz, Cyrille Nadal, Victor Poupet, Gilles Trombettoni, Petru Valicov
- 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.
- Vous respecterez les différents principes de programmation vus dans le cours et les TPs précédents
- Toutes vos classes doivent résider dans le paquetage
fr.umontpellier.iut
- Les signatures des méthodes et les noms des classes qui vous sont données doivent rester inchangés.
Date limite de rendu de votre code sur le dépôt GitLab : dimanche 19 mai à 23h00
Reprenons la classe Employe
du TP5. Pour vous faciliter la tâche, nous l'avons directement écrite et simplifiée en enlevant les attributs inutiles pour ce TP. Un attribut dateEmbauche
avec accesseur et modifieur ont été ajoutés à la classe Employe
. Le but de ce TP est de proposer différentes organisations des employés dans l'entreprise en fonction des besoins du client.
-
La classe
Entreprise
gère les employés à travers l'attributlePersonnel
- uneCollection
(la structure de données itérable la plus générale possible). Ajoutez un constructeur sans paramètres instanciant cette collection en tant queArrayList
. -
Complétez les méthodes
void embaucher(Employe e, LocalDate dateEmbauche)
etvoid licencier(Employe e)
de la classeEntreprise
afin de mettre à jour la liste d'employés de manière correspondante. Lors du licenciement de l'employé, vous mettrez ànull
sa date d'embauche. -
Redéfinissez la méthode
String toString()
de la classeEntreprise
pour afficher ses informations. -
Vérifiez votre programme en créant dans la classe principale (
GestionEmployes
) une entreprise et en embauchant plusieurs employés. Vous afficherez l'état de l'entreprise après chacune des opérations.
L'entreprise souhaite mieux organiser ses employés.
-
Redéfinissez les méthodes
equals(Object o)
ethashCode()
de la classeEmploye
afin de distinguer deux employés en fonction de leur numéro INSEE et leur nom (de typeString
). Dorénavant deux employés seront considérés comme des doublons s'ils ont le même numéro INSEE et le même nom.Remarque importante : votre méthode
licencier(Employe e)
supprime la première occurrence de l'employée
au sens deequals
(même numéro INSEE et même nom). Or, la collectionlePersonnel
peut contenir le même employé (au sens deequals
) plusieurs fois si cette personne occupe des postes différents. Dans ce cas, votre méthodelicencier(Employe e)
va maintenant licencier l'employé de l'un de ses postes, mais pas de l'autre, sans qu'on puisse contrôler quel poste est visé.
En conclusion, la méthodelicencier
n'est pas faite pour traiter le cas où un employé a été embauché à plusieurs postes. Ne changez pas la méthodelicencier
pour autant. -
Écrivez le corps de la méthode
Collection<Employe> getEmployesDansDesordre()
. À partir de la collectionlePersonnel
, elle devra retourner une autre collection en enlevant tous les doublons, et ce, sans invoquer explicitement un algorithme de recherche de doublons.Attention : Pas de modifications du code précédemment écrit (et donc de l'attribut
lePersonnel
). -
Maintenant, pour une meilleure lisibilité, l'entreprise souhaite pouvoir retrouver l'ensemble de ses employés sans les doublons, mais dans l'ordre. L'ordre choisi est l'ordre croissant suivant le nom et qui en cas d'égalité, applique l'ordre décroissant suivant le numéro INSEE.
Écrivez le corps de la méthode
Collection<Employe> getEmployesOrdonnes()
qui, à partir de la collectionlePersonnel
, retourne une autre collection respectant ces contraintes. Naturellement, comme dans la question précédente, il ne faut pas écrire ou invoquer explicitement un algorithme de recherche de doublons, ni un algorithme de tri.Remarque : les deux fonctions
getEmployesDansDesordre()
etgetEmployesOrdonnes()
doivent être totalement indépendantes et ne doivent pas s'appeler entre elles.
Pensez à écrire plusieurs tests unitaires vérifiant les fonctionnalités programmées.
L'entreprise souhaite distribuer des bonus à ses employés en fonction de la date d'embauche. Le problème est que cette somme est évidemment limitée, donc on risque de ne pas pouvoir distribuer des bonus à chaque employé... Cette somme est représentée par l'attribut double bonusTotal
de la classe Entreprise
. Un setter permet à l'utilisateur de fixer à tout moment la somme d'argent disponible pour distribuer un bonus aux employés.
L'attribut double bonus
de la classe Employe
permet de définir la quantité de bonus qu'un employé va recevoir. Les méthodes setter et getter permettent la gestion de ce bonus.
-
Dans la classe
Employe
la méthodeint getMoisAnciennete()
renvoie le nombre de mois correspondant à l'intervalle de temps entre la date d'embauche et maintenant. Le corps de cette méthode vous est donné et vous ne devez pas le modifier. L'ancienneté est calculée sur le nombre de mois complets depuis la date d'embauche à l'aide du type énuméréChronoUnit
. Cette classe permet d'effectuer des calculs en fonction de différentes unités temporelles (jours, mois, années, etc.).Écrivez plusieurs tests unitaires afin de comprendre le fonctionnement de la méthode
int getMoisAnciennete()
de la classeEmploye
. Vérifiez notamment que deux personnes étant embauchées à des dates différentes, mais ayant effectué le même nombre de mois complets aient la même ancienneté. Par exemple, un employé embauché depuis 10 mois et 14 jours aura la même ancienneté qu'un employé embauché depuis 10 mois. Prêtez attention à la variation des longueurs des mois dans une année ! -
Le patron a décidé de donner la priorité aux anciens pour la distribution du bonus. Ainsi, le bonus sera distribué aux employés suivant leurs dates d'embauche : de la plus ancienne, à la plus récente. Chaque employé va voir son bonus incrémenté de
3.5 * getMoisAncienneté()
. Écrivez le corps de la méthodevoid distribuerBonus()
qui effectue cette tâche sans utiliser explicitement un algorithme de tri et sans modifier la classeEmploye
Écrivez des tests unitaires pour vous assurer que chaque employé a bien reçu le bon bonus. Attention : seule la date d'embauche exacte (et pas l'ancienneté en mois) doit servir comme critère pour déterminer l'ordre de distribution du bonus.Remarques :
- Pour déterminer l'ordre de distribution du bonus de deux employés embauchés à des dates identiques, vous prendrez l'ordre d'apparition dans la collection
lePersonnel
. - Un employé embauché à plusieurs postes (qui apparaît plusieurs fois dans
lePersonnel
), percevra plusieurs fois le bonus. - Le bonus étant limité, il se peut que certains employés ne touchent rien (notamment les plus jeunes). De même, si vers la fin de la distribution, la quantité de bonus restante est inférieure à
3.5*ancienneté
, alors l'employé recevra seulement la quantité de bonus restante et tant pis pour son ancienneté !
- Pour déterminer l'ordre de distribution du bonus de deux employés embauchés à des dates identiques, vous prendrez l'ordre d'apparition dans la collection
-
Modifiez la méthode
toString()
deEmploye
afin qu'elle affiche également le bonus que l'employé a reçu. -
L'entreprise traverse une période de crise et décide de se séparer d'une partie de ses employés. Afin de fidéliser les anciens employés, ce qui a été décidé, c'est de licencier les employés ayant travaillé le moins longtemps dans l'entreprise. Sans modifier le code précédemment écrit, écrivez le code de la méthode
void remercier(int n)
de la classeEntreprise
pour licenciern
employés ayant été embauchés le plus tard.Remarques importantes : Comme dans le cas de la question 2, si deux employés sont embauchés à des dates identiques, vous les remercierez dans l'ordre d'apparition dans la collection
lePersonnel
. Également, un employé peut être licencié d'un poste, mais pas d'un autre.Astuce : Pour cette question, pensez à vérifier le scénario suivant :
- Créer 3 employés comme ceci
- 2 employés fifi et loulou avec le même numéro INSEE et le même nom et des bases différentes
- 1 employé toto avec numéro INSEE, nom et base quelconques
- Embaucher d'abord toto avec une date d'embauche la plus ancienne (disons 1er janvier 2000), ensuite fifi (2 mai 2024) et ensuite loulou (30 mai 2024)
- Remercier qu'un seul employé en invoquant
remercier(1)
et vérifier que tout fonctionne correctement.
- Créer 3 employés comme ceci
On souhaite maintenant pouvoir calculer les indemnités de transport pour chaque employé en fonction de la distance entre sa ville de résidence (une donnée de type String
) et les locaux de l'entreprise.
La classe GestionDistances
gère une collection statique faisant correspondre une distance (un entier) à une ville. Il s'agit d'une Map
. Une ville ne peut être associée qu'à une unique distance, mais une même distance peut être associée à plusieurs villes. La Map
est initialisée avec les données suivantes :
- Montpellier → 0
- Sète → 36
- Sommières → 30
- Nîmes → 58
- Lunel → 30
- Béziers → 80
Attention : la collection distances
est statique, donc n'ajoutez pas de constructeur à la classe GestionDistances
...
-
Déclarez une classe d'exception contrôlée
VilleInconnueException
héritant deException
. Le constructeur de cette classe aura comme argument un objetString nomVille
et appellera le constructeur de la classe de base (Exception
) avec le message : "La ville " +nomVille
+ ” n'existe pas” -
La méthode
static int getDistance(String ville)
deGestionDistances
devra retourner la distance associée à la ville passée en paramètre. Modifiez la signature de cette fonction annonçant qu'elle est susceptible de lever une exceptionVilleInconnueException
. Écrivez ensuite le corps destatic int getDistance(String ville)
en veillant à ce qu'elle lève une exceptionVilleInconnueException
si la ville n'est pas présente dans la collectiondistances
. -
Écrivez le corps de la méthode
double getIndemniteTransport()
de la classeEmploye
. Elle doit retourner l'indemnité qui est due à l'employé. La formule de calcul de cette indemnité estdistance * base
. Si la ville n'existe pas, cette méthode devra traiter l'exception correspondante et retourner0
.