Atelier 4 : Système de Restaurant Refactorisé avec Classes, Exceptions et Tests
Objectifs
- Refactoriser le code procédural (Atelier 2) en code orienté objet
- Appliquer les exceptions pour valider les données
- Écrire des tests unitaires pour valider le comportement
- Gérer les cas d'erreur sans faire planter le programme
Contexte
Vous avez créé un système de restaurant basique dans l'atelier 2 avec des méthodes statiques. Maintenant, il faut le refactoriser en utilisant :
- Des classes pour structurer le code (
MenuItem,Commande) - Des validations dans les classes qui lèvent des exceptions
- Une gestion globale des exceptions dans le
mainpour éviter les crashes - Des tests unitaires pour valider le bon fonctionnement
Partie 1 : Créer les classes
Classe MenuItem
Créez une classe MenuItem pour représenter chaque item du menu :
Attributs :
int numero- Le numéro de l'item (1-5)String nom- Le nom de l'itemdouble prix- Le prix de l'item
Constructeur :
- Valide que le numéro est >= 1
- Valide que le nom n'est pas null ou vide
- Valide que le prix n'est pas négatif
- Lève
IllegalArgumentExceptionsi les validations échouent
Getters :
getNumero()getNom()getPrix()
Classe Commande
Créez une classe Commande pour gérer une commande cliente :
Attributs :
MenuItem[] items- Les items commandésint[] quantites- Les quantités correspondantesstatic final double TAUX_TAXES = 0.15- Taux de taxes (15%)
Constructeur :
- Initialise les tableaux pour stocker les items et quantités
Méthodes publiques :
-
ajouterItem(MenuItem item, int quantite): Ajoute un item à la commande- Valide que l'item n'est pas null
- Valide que la quantité est > 0
- Lève
IllegalArgumentExceptionsi invalide
-
calculerSousTotal(): Retourne le total avant taxes et pourboire -
calculerTaxes(): Retourne le montant des taxes (sous-total × 0.15) -
calculerPourboire(int pourcentage): Retourne le pourboire- Valide que le pourcentage est entre 0 et 100
- Lève
IllegalArgumentExceptionsi invalide
-
calculerTotal(int pourcentagePourboire): Retourne le total final -
afficherRecu(int pourcentagePourboire): Affiche un reçu formaté- Affiche chaque item avec sa quantité et son prix partiel
- Affiche le sous-total, les taxes, le pourboire et le total
-
isEmpty(): Retourne true si la commande est vide
Partie 2 : Classe Restaurant avec Menu et Gestion d'Erreurs
Créez une classe Restaurant :
Attribut d'instance :
MenuItem[] menu- Tableau contenant les 5 items du menu (NON statique)
Constructeur : Créez un constructeur qui initialise le menu avec les 5 MenuItem :
public class Restaurant {
private MenuItem[] menu;
public Restaurant() {
// Initialiser le menu dans le constructeur
menu = new MenuItem[5];
menu[0] = new MenuItem(1, "Burger", 12.99);
menu[1] = new MenuItem(2, "Pizza", 15.99);
menu[2] = new MenuItem(3, "Salade", 9.99);
menu[3] = new MenuItem(4, "Poutine", 8.99);
menu[4] = new MenuItem(5, "Boisson", 2.99);
}
public static void main(String[] args) {
// Créer une instance de Restaurant
Restaurant restaurant = new Restaurant();
Scanner clavier = new Scanner(System.in);
// Appeler les méthodes sur l'instance
restaurant.afficherMenu();
// ... etc
}
}
Méthode main(String[] args) :
- Créer une instance de
Restaurant - Créer un
Scanner - Afficher un message de bienvenue
- Boucle permettant de prendre plusieurs commandes
- Gère TOUTES les exceptions (IllegalArgumentException, InputMismatchException, etc.)
- Affiche les erreurs sans faire planter le programme
- Demande si l'utilisateur veut une autre commande
- Fermer le Scanner à la fin
Méthodes d'instance (NON statiques) :
-
afficherMenu()- Affiche le menu du restaurant formaté===== MENU DU RESTAURANT =====1. Burger ..................... 12.99$2. Pizza ....................... 15.99$... -
prendreCommandes(Scanner clavier): Retourne une Commande- Boucle permettant d'ajouter plusieurs items
- Demande le numéro de l'item et la quantité
- Arrête quand l'utilisateur entre 0
- Gère les exceptions (InputMismatchException, IllegalArgumentException)
- Affiche les erreurs sans interrompre
-
demanderPourboire(Scanner clavier): Retourne un pourcentage (10, 15 ou 20)- Boucle
do-whilejusqu'à un choix valide - Valide que le pourcentage est 10, 15 ou 20
- Gère les InputMismatchException
- Boucle
Partie 3 : Tests Unitaires avec JUnit
Créez une classe MenuItemTest.java dans src/test/java:
Tests à écrire :
- Constructor avec données valides
- Constructor avec numéro invalide (0 ou négatif)
- Constructor avec nom vide ou null
- Constructor avec prix négatif
- Constructor avec prix égal à 0 (valide)
Créez une classe CommandeTest.java dans src/test/java:
Tests à écrire :
- Ajouter un item (cas nominal)
- Ajouter plusieurs items et calculer le sous-total
- Calculer les taxes correctement
- Calculer le pourboire avec différents pourcentages
- Calculer le total final
- Ajouter un item null (exception attendue)
- Ajouter une quantité négative (exception attendue)
- Calculer pourboire avec pourcentage invalide (exception attendue)
- isEmpty() retourne true pour commande vide
- isEmpty() retourne false pour commande non vide
Travail à faire
- Créez les deux classes
MenuItemetCommandeavec validations et exceptions - Créez la classe
Restaurantavec gestion des erreurs dans le main - Écrivez les tests unitaires pour couvrir tous les cas
- Testez manuellement que le programme ne plante pas quelle que soit l'entrée
- Améliorez le code pour ajouter des fonctionnalités au besoin
Points importants
- Les exceptions doivent être levées dans les classes quand les données sont invalides
- Le main doit attraper toutes les exceptions et afficher un message d'erreur
- Le programme doit continuer à fonctionner même après une erreur
- Les tests doivent vérifier les cas normaux ET les cas d'erreur
- Utilisez
try-catchpour gérer lesInputMismatchExceptiondu Scanner
Pour aller plus loin?
- Ajouter la persistance des données (fichier ou base de données)