Aller au contenu principal

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 :

  1. Des classes pour structurer le code (MenuItem, Commande)
  2. Des validations dans les classes qui lèvent des exceptions
  3. Une gestion globale des exceptions dans le main pour éviter les crashes
  4. 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'item
  • double 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 IllegalArgumentException si 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és
  • int[] quantites - Les quantités correspondantes
  • static 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 IllegalArgumentException si 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 IllegalArgumentException si 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) :

  1. afficherMenu() - Affiche le menu du restaurant formaté

    ===== MENU DU RESTAURANT =====
    1. Burger ..................... 12.99$
    2. Pizza ....................... 15.99$
    ...
  2. 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
  3. demanderPourboire(Scanner clavier) : Retourne un pourcentage (10, 15 ou 20)

    • Boucle do-while jusqu'à un choix valide
    • Valide que le pourcentage est 10, 15 ou 20
    • Gère les InputMismatchException

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

  1. Créez les deux classes MenuItem et Commande avec validations et exceptions
  2. Créez la classe Restaurant avec gestion des erreurs dans le main
  3. Écrivez les tests unitaires pour couvrir tous les cas
  4. Testez manuellement que le programme ne plante pas quelle que soit l'entrée
  5. 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-catch pour gérer les InputMismatchException du Scanner

Pour aller plus loin?

  • Ajouter la persistance des données (fichier ou base de données)