Introduction
Un comptoir communautaire prête des outils physiques à des membres inscrits. Deux perceuses peuvent porter le même nom tout en relevant de prêts différents. Un outil en maintenance doit rester indisponible, et seul l’emprunteur enregistré peut rendre un outil emprunté.
Vous intégrerez ces règles à un objet Java, puis utiliserez une petite boucle de commandes fournie. Ce premier lab conserve les modifications en mémoire ; le suivant enseigne leur enregistrement. Vous devez déjà connaître les classes, les méthodes, les champs privés, les listes et les exceptions de base en Java. Durée de lecture et de pratique estimée par l’auteur : 45 minutes.
Prêter un outil sans perdre son identité
Dans cette étape, vous exécuterez un prêt normal, lirez l’objet fourni et ajouterez la petite règle qui le protège contre un deuxième prêt.
Ouvrez l’onglet Terminal. cd sélectionne le dossier ; toutes les commandes shell ultérieures de ce lab partent de celui-ci. Si une ligne mal saisie n’a pas encore été exécutée, appuyez sur Ctrl+U pour l’effacer, puis ressaisissez-la. Si « file not found » apparaît, réexécutez ce cd au lieu de réinitialiser l’environnement.
cd /home/labex/project/tool-library
L’application fournie compile déjà. javac est le compilateur Java, -encoding UTF-8 précise l’encodage du code source, -d out place les classes compilées dans out, et *.java sélectionne les fichiers sources Java du dossier.
javac -encoding UTF-8 -d out *.java
Une compilation réussie n’affiche rien. Après toute modification, compilez avec succès avant chaque lancement ; sinon Java pourrait exécuter d’anciennes classes. java lance le programme, -Dfile.encoding=UTF-8 sélectionne son encodage de texte, -cp out sélectionne les classes compilées et Desk est la classe d’entrée. desk.tsv fournit les enregistrements ; --memory désactive l’enregistrement dans ce lab.
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Vous êtes dans le programme du comptoir, et non dans le shell. Saisissez chaque ligne en appuyant sur Enter après chacune :
borrow A11 M01
list
quit
Vous devez obtenir Accepted: A11 BORROWED M01. A12 est une autre Drill et reste AVAILABLE : l’ID identifie un outil physique, tandis que son nom peut se répéter. quit revient au shell. Ce prêt normal fonctionne avant la correction, mais le code n’empêche pas encore un deuxième prêt du même outil. Comme cette exécution utilise --memory, le fichier original reste inchangé et l’exécution suivante repart de zéro.
Lisez le code source fourni avec cat, qui affiche un fichier sans le modifier :
cat Tool.java
Un outil possède un id stable, un name d’affichage, un state, un borrower et une note. Un enum comporte un ensemble fixe de valeurs nommées : AVAILABLE indique que personne ne détient l’outil, BORROWED qu’un membre le détient et MAINTENANCE que le prêt est bloqué. Le tiret - représente l’absence d’emprunteur. Les champs privés ne peuvent changer que par les méthodes. Lisez borrow : cette méthode affecte actuellement BORROWED et un nouveau membre sans vérifier l’ancien état. Prévoyez ce qu’un deuxième prêt écraserait. Le constructeur, les accesseurs et l’enum sont déjà complets ; conservez-les.
La structure de la boucle de commandes est également fournie :
cat Desk.java
Repérez l’appel found.borrow(c[2]) et le try/catch qui l’entoure. La boucle vérifie que l’ID du membre existe, mais un Tool doit protéger son propre état. Une IllegalArgumentException devient Rejected: ... et la boucle reste ouverte. Le contrôle d’état doit avoir lieu avant les deux affectations ; lever l’exception après une modification laisserait un prêt refusé partiellement appliqué.
Avant de modifier le code, faites une sauvegarde des sources uniquement. mkdir -p crée un dossier au besoin ; cp copie un fichier. Ce sont vos propres sauvegardes, pas des réponses complètes. Ne copiez ni ne réinitialisez les données du comptoir ou des membres.
mkdir -p work
cp Tool.java work/Tool-before-borrow.java.txt
Ouvrez le fichier existant dans nano, un éditeur de texte pour le terminal :
nano Tool.java
Dans nano, ^ dans la barre des raccourcis signifie Ctrl. Maintenez Ctrl en appuyant sur l’autre touche ; ne saisissez pas l’accent circonflexe. Appuyez sur Ctrl+W, saisissez state = State.BORROWED;, puis appuyez sur Enter pour trouver l’affectation dans borrow. Appuyez sur Ctrl+A pour aller au début de cette ligne. Utilisez les flèches pour placer le curseur et Backspace pour corriger les caractères. Insérez cette garde au-dessus de l’affectation, en conservant les deux affectations existantes et le reste de la classe :
if (state != State.AVAILABLE) {
throw new IllegalArgumentException("Tool is not available");
}
Ici, != signifie « n’est pas égal à ». La condition refuse aussi bien un prêt existant que la maintenance ; elle ne modifie ni l’identité, ni le nom, ni la note. Écrivez cette branche dans votre méthode existante au lieu de remplacer la classe. Vérifiez les accolades et le point-virgule.
Appuyez sur Ctrl+O pour enregistrer, Enter pour confirmer le nom de fichier existant, puis Ctrl+X pour quitter. Pour abandonner une erreur non enregistrée, appuyez sur Ctrl+X et répondez N à la demande d’enregistrement. Rouvrez le fichier pour réessayer. Depuis le shell, nano Tool.java le rouvre ; Ctrl+W retrouve le même repère. En cas d’erreur de compilation, lisez le nom de fichier et la ligne, corrigez cet emplacement dans nano, enregistrez et recompilez. Ne lancez pas le programme après une compilation échouée.
Pour annuler toutes les modifications du code source de cette étape, la commande de récupération suivante restaure uniquement votre sauvegarde antérieure de Tool.java. Elle supprime ces modifications : utilisez-la seulement si vous voulez recommencer cette modification du code source ; elle ne réinitialise jamais les données. C’est une option de récupération, pas l’étape suivante normale :
cp work/Tool-before-borrow.java.txt Tool.java
Après avoir enregistré la garde (ou l’avoir refaite après récupération), compilez et lancez :
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Saisissez ces commandes du comptoir dans l’ordre :
borrow A11 M01
list
borrow A11 M02
borrow A13 M01
borrow TYPO M01
borrow A12 M02
list
quit
Le premier prêt est accepté. Le second prêt du même outil et le prêt de l’outil en maintenance sont volontairement refusés avec Rejected: Tool is not available. TYPO produit un refus pour ID inconnu ; corrigez l’ID à la ligne suivante sans réinitialiser. A12 peut toujours être empruntée indépendamment par M02. La liste finale doit conserver A11 → M01 ainsi que l’état et la note de maintenance de A13. quit revient au shell ; desk.tsv reste inchangé. La méthode de retour est encore incomplète : ce sera le travail de l’étape suivante.
Autoriser uniquement l’emprunteur enregistré à rendre l’outil
Dans cette étape, vous compléterez la transition inverse tout en préservant les autres prêts.
Partez de l’invite du shell dans le même onglet Terminal. Un retour est valide uniquement depuis BORROWED, et seulement si le membre indiqué correspond à borrower. Pour les chaînes Java, .equals() compare leur contenu ; ! inverse cette comparaison. Une fois les deux vérifications satisfaites, définissez l’état sur AVAILABLE et effacez l’emprunteur en lui attribuant -. Lever d’abord l’exception empêche un retour refusé de modifier partiellement l’objet.
Conservez votre garde de prêt. Avant la prochaine modification, faites une nouvelle sauvegarde des sources uniquement pour qu’une récupération conserve la méthode de prêt terminée :
cp Tool.java work/Tool-before-return.java.txt
nano Tool.java
Appuyez sur Ctrl+W, recherchez state = State.AVAILABLE;, puis appuyez sur Enter. Il s’agit de la première affectation dans giveBack. Appuyez sur Ctrl+A pour aller au début de cette ligne. Insérez les deux contrôles ci-dessous avant elle ; conservez l’affectation d’état existante et borrower = "-"; après les deux contrôles. Ne remplacez pas la classe et ne supprimez pas la garde de prêt.
if (state != State.BORROWED) {
throw new IllegalArgumentException("Tool is not borrowed");
}
if (!borrower.equals(member)) {
throw new IllegalArgumentException("Borrower does not match");
}
La première branche refuse un outil disponible ou en maintenance. Seul un outil emprunté atteint le contrôle d’identité. Comparez le membre avec l’emprunteur enregistré, pas avec un nom d’affichage. Vérifiez les accolades, puis utilisez Ctrl+O, Enter, Ctrl+X pour enregistrer et quitter. En cas d’erreur non enregistrée, Ctrl+X, N l’abandonne. Corrigez les erreurs de compilation en rouvrant le fichier et en recherchant la méthode concernée ; compilez avec succès avant de lancer. Pour supprimer volontairement les modifications de cette étape tout en gardant la garde de prêt, utilisez cp work/Tool-before-return.java.txt Tool.java, puis refaites uniquement la modification du retour. Ne restaurez pas l’ancienne sauvegarde précédant la garde de prêt.
Recompilez pour que le programme utilise le code source actuel, puis ouvrez un nouveau comptoir en mémoire. Chaque exécution de ce lab repart du fichier original.
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Saisissez ces commandes du comptoir dans l’ordre :
list
return A14 M01
return A13 M03
return A14 M03
borrow A14 M02
list
quit
La première liste montre le prêt existant A14 → M03. Le mauvais emprunteur reçoit Rejected: Borrower does not match. Le retour de l’outil en maintenance produit Rejected: Tool is not borrowed. Aucun de ces refus ne modifie l’objet. Le bon retour produit Accepted: A14 AVAILABLE -, puis M02 peut emprunter l’outil. A13 reste en maintenance ; A11 et A12 conservent leurs ID et leurs notes distincts.
Vous avez exprimé deux transitions autorisées : AVAILABLE → BORROWED et BORROWED → AVAILABLE. Il n’existe aucune transition de retour depuis MAINTENANCE, et cette application ne propose pas de commande de gestion de maintenance. Un refus est un résultat métier normal ; il ne termine pas la boucle de commandes. Vous pouvez relancer le programme pour vous entraîner. Dans ce lab, les modifications disparaissent volontairement après quit ; conservez votre code source et poursuivez avec le lab indépendant sur la persistance pour comprendre pourquoi.
Résumé
Vous avez utilisé un enum et l’état privé d’un objet pour protéger les prêts d’outils. Les outils homonymes ont conservé des ID distincts, les actions invalides ont préservé l’objet et un retour valide a permis un nouveau prêt à un autre membre. La conservation des résultats entre exécutions est le prochain objectif.



