- Cours: M2103 - support ici
- Enseignants: Marin Bougeret, Sébastien Gagné, Sophie Nabitz, Jérôme Palaysi, Victor Poupet, 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.
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.
- Vous respecterez toutes les consignes indiquées dans le TP précédent
- Vous respecterez les conventions de nommage Java (vues en cours ou disponibles sur le site d'Oracle). Prêtez une attention particulière au respect des noms de classes, attributs et méthodes qui vous seront demandés.
- Dans ce TP, un principe important que vous devriez essayer de respecter dans votre code est le principe DRY.
- Pour chaque question nécessitant une vérification automatique, vous écrirez des tests unitaires, pour valider votre solution. Une solution sans aucun test sera considérée comme non-valide.
- Vous noterez vos réponses aux questions du sujet dans un fichier reponses.md que vous déposerez à la racine de votre dépôt Git.
Cliquez sur le lien ci-dessous pour faire votre fork privé du TP :
https://classroom.github.com/a/b0wjVQmn
Date limite de rendu de votre code sur le dépôt GitHub : Dimanche 1 mars à 23h00
Vous êtes chargés de proposer une application de gestion des employés dans une entreprise. L’objectif est de développer votre application de manière incrémentale, en ajoutant les fonctionnalités demandées au fur et à mesure sans modifier les fonctionnalités écrites précédemment. Ce que l'on considère ici comme modification c'est effacer et/ou réécrire du code précédemment écrit. Ajouter du code sans modifier le code précédent est donc une opération valide. On dira ici, que pour chaque modification de votre programme (effacement et réécriture) la dette de votre logiciel augmente. Afin de respecter les divers principes en programmation orientée objets (encapsulation, DRY, YAGNI etc.), vous essayerez d'éviter au maximum de modifier le programme écrit précédemment pour ne pas trop augmenter cette dette...
Dans tout ce TP, tous les attributs devraient être private
(en particulier il est très déconseillé d'utiliser la visibilité protected
pour les attributs).
-
Dans un premier temps vous devez modéliser les employés représentés par les données suivantes : numéro de sécurité sociale, nom, échelon (entier naturel). Pour pouvoir calculer le salaire brut et le salaire net d'un employé, deux attributs supplémentaires de type
double
sont nécessaires :base
etnbHeures
. Implémentez la classeEmploye
correspondante et ajoutez-y le constructeur suivant (avec les paramètres dans cet ordre) :public Employe(String nrINSEE, String nom, int echelon, double base, double nbHeures)
-
Le constructeur ayant beaucoup de paramètres, il vous est également demandé de proposer un builder pour une construction plus souple (cf. question 5, Exercice 3 du TP3). Vous pouvez générer le builder de manière automatique avec l'outil de refactoring d'IntelliJ IDEA :
-
Le salaire brut de l’employé se calcule de la manière suivante :
base * nbHeures
. Le salaire net représentera toujours 80% du salaire brut. Ajoutez le code nécessaire (attributs et méthodes) pour intégrer ces fonctionnalités et proposez des méthodes respectivesgetSalaireBrut()
etgetSalaireNet()
. -
Redéfinissez la méthode
String toString()
dans la classeEmploye
pour afficher les informations concernant un employé (y compris ses salaires brut et net). -
Si votre client vous demande de changer (modifier donc) la formule de calcul du salaire brut et de la fixer à
base * nbHeures * 1.05
, combien de changement devriez-vous effectuer pour que votre programme continue de fonctionner correctement ? Est-ce que vous pouvez faire mieux ? Remarque : comme convenu précédement, dans ce qui suit, le salaire brut d'un employé restera toujours le même, à savoirbase * nbHeures
-
Vérifiez votre solution dans le programme principal (la classe
GestionEmployes
). Vous y instancierez plusieurs employés (avec le builder) et afficherez les informations les concernant. N'oubliez pas les tests unitaires pour les exercices précédents !
-
Avec le développement de l'entreprise, une séparation des traitements pour les différents types d'employés devient nécessaire. Il faut spécifier les cas des Commerciaux, Fabricants, et les autres employés qu’on appellera Techniciens.
- La classe
Commercial
a comme attributschiffreAffaires
ettauxCommission
(tous les deux de typedouble
). - La classe
Fabricant
a comme attributsnbUnitesProduites
ettauxCommissionUnite
(typeint
etdouble
respectivement). - La classe
Technicien
n'a pour l'instant aucun nouveau attribut, ni aucune nouvelle méthode.
Implémentez les classes correspondantes en les faisant hériter de la classe
Employe
. Voici la signature des constructeurs de ces classes :public Commercial(String nrINSEE, String nom, int echelon, double base, double nbHeures, double chiffreAffaires, double tauxCommission) public Fabricant(String nrINSEE, String nom, int echelon, double base, double nbHeures, int nbUnitesProduites, double tauxCommissionUnite) public Technicien(String nrINSEE, String nom, int echelon, double base, double nbHeures)
Ne générez pas des builders pour ces classes pour le moment.
- La classe
-
Un commercial peut négocier des transactions (avec la méthode
void negocierTransaction()
), un fabricant fabrique des produits (méthodevoid fabriquerProduit()
), un technicien effectue les autres tâches dans l’entreprise (méthodevoid effectuerTacheTechnique()
). Toutes ces méthodes est de typevoid
et se contentent d'afficher un message approprié pour illustrer leur bon fonctionnement. Par exemple, la méthodevoid negocierTransaction()
devra afficher ”Je négocie une transaction”. -
Vérifiez votre programme dans la classe principale, en instanciant un objet pour chaque nouveau type d'employé et en appelant sa fonction spécifique.
-
On souhaite varier le calcul des salaires bruts des différents types d’employés :
- Le salaire brut d’un technicien est composé de son salaire brut en tant qu’employé + une majoration
en fonction de son échelon. Dans notre exemple, le résultat de ce calcul devrait correspondre à
base ∗ nbHeures + echelon ∗ 100
. - Le salaire brut d’un commercial dépend du chiffre d’affaires qu’il réalise. Ainsi, le salaire brut se calcule
suivant la formule
base + chiffreAffaires ∗ tauxCommission
. - Le salaire brut d’un fabricant est calculé de la même manière que le salaire brut d’un employé en ajoutant une
rémunération supplémentaire en fonction du rendement. Dans notre exemple, le résultat de ce calcul devrait
correspondre à
base ∗ nbHeures + nbUnitesProduites ∗ tauxCommissionUnite
. - Important : La modalité de calcul du salaire net demeure inchangée pour tous les employés (à savoir 80% du salaire brut).
Redéfinissez la méthode
getSalaireBrut()
dans chaque classe d'employé spécifique pour prendre en compte ces nouvelles formules. Vous ajouterez le code qui vous paraît nécessaire à la classeEmploye
mais sans modifier le code précédemment écrit. - Le salaire brut d’un technicien est composé de son salaire brut en tant qu’employé + une majoration
en fonction de son échelon. Dans notre exemple, le résultat de ce calcul devrait correspondre à
-
Déclarez un objet de type
Employe
et instanciez-le en tant queFabricant
. Observez le résultat de l'appel des méthodesgetSalaireBrut()
etgetSalaireNet()
. Est-ce que la méthodefabriquerProduit()
est accessible ? Expliquez en comparant avec le scénario où l'objet serait déclaré en tant queFabricant
. -
Si le patron devient plus généreux et décide d’ajouter 100€ au salaire brut de tous ses employés, combien de modifications devez-vous apporter à votre code pour que cela fonctionne ?
-
Maintenant, votre client se rend compte qu’un
Commercial
ne peut pas être un simple commercial (donc ne peut pas être instancié en tant que tel), mais doit être distingué en tant queVendeur
ouReprésentant
. Un vendeur doit peut vendre des produits (méthodevoid vendreProduit()
) et un représentant peut représenter l'entreprise auprès des différents clients (méthodevoid representerEntreprise()
). Ajoutez les deux classes correspondantes en faisant un héritage deCommercial
. Vous ajouterez également à la classeCommercial
, le code nécessaire afin que cette classe ne soit pas instanciable. Voici la signature des constructeurs de ces classes :public Vendeur(String nrINSEE, String nom, int echelon, double base, double nbHeures, double chiffreAffaires, double tauxCommission) public Representant(String nrINSEE, String nom, int echelon, double base, double nbHeures, double chiffreAffaires, double tauxCommission)
-
Implémentez les builders pour les classes
Technicien
,Fabricant
,Representant
etVendeur
. Remarque : Observez la duplication de code entre les différentes classes builders (non-respect du principe DRY). Pour le moment, pour des raisons de facilité nous allons tolérer ce défaut et laisser les classes builders telles qu'elles. Dans quelques semaines, après avoir suffisamment avancé dans le cours, nous y reviendront pour améliorer. Pour les curieux : https://stackoverflow.com/questions/21086417/builder-pattern-and-inheritance Une explication approfondie et une solution sont également données dans Effective Java de J. Blosch, (3ème édition). -
Pour terminer, faites en sorte que la méthode de calcul du salaire brut d'un vendeur soit toujours la même que la méthode de calcul du salaire brut d'un commercial, alors que la formule de calcul du salaire brut des représentants soit toujours la même que celle utilisée pour le salaire brut des techniciens. Ajoutez cette fonctionnalité dans votre application.
Attention à ne pas dupliquer du code (principe DRY) et à ne pas modifier le code précédemment écrit ! Sinon la dette de votre logiciel va augmenter. 😏
-
Quels sont les avantages et inconvénients de votre approche ?
-
Dessinez le diagramme de classes afin de mieux comprendre votre solution. Vous déposerez le diagramme sous forme d'image (.png ou .jpg) à la racine de votre dépôt Git.
Note : les builders ne doivent pas faire partie de votre diagramme de classes