Skip to content

Sommatif no. 3 - Collections et Exceptions

Contexte général

Vous travaillez pour une petite boutique en ligne qui gère :

  • une file de commandes en attente, représentée par une LinkedList<Commande> ;
  • un registre de clients, représenté par une HashMap<String, Client> où la clé est l’id du client.

Vous allez :

  • manipuler deux collections (LinkedList et HashMap) ;
  • parcourir ces collections à l’aide d’un Iterator (pas de for-each) ;
  • créer et utiliser des exceptions personnalisées contenant l’objet en erreur ;
  • trier une liste de commandes à l’aide d’un Comparator<Commande> basé sur la couleur (java.awt.Color).
    L’ordre de priorité des couleurs est :
    • Noir > Rouge > Bleu > Jaune

Travail demandé (instructions de réalisation)

Modèle de données

  1. Créez une classe Client avec au minimum :

    • String id
    • String nom
    • double solde
      ainsi que les constructeurs, getters, setters nécessaires et une méthode toString() lisible.
  2. Créez une classe Commande avec au minimum :

    • String id
    • String clientId
    • String description
    • int quantite
    • double prixUnitaire
    • java.awt.Color color
      plus un constructeur, les getters nécessaires et une méthode toString().
  3. Vérifiez que votre classe Commande importe correctement la classe Color :

    import java.awt.Color;
    


Exceptions personnalisées

  1. Créez une classe abstraite CollectionOperationException qui étend Exception et contient :

    • un champ Object objectInError
    • un constructeur permettant d’initialiser le message et l’objet en erreur
    • un getter getObjectInError()
  2. Créez les trois exceptions concrètes suivantes, qui héritent toutes de CollectionOperationException :

    • InvalidOrderException

      • doit prendre en paramètre une Commande en erreur
    • UnknownClientException

      • peut prendre en paramètre une Commande ou un clientId (String) en erreur
    • NegativeBalanceException

      • doit prendre en paramètre un Client en erreur
  3. Dans chaque exception concrète, appelez le constructeur de la classe mère (super(...)) avec un message explicite et l’objet en erreur.


Service métier et itérateurs

Créez une classe OrderService qui contiendra les méthodes statiques suivantes :

  1. validerFileCommandes(LinkedList<Commande> fileCommandes)

    • Utilise un Iterator<Commande> pour parcourir la liste.
    • Si une commande a quantite <= 0 ou prixUnitaire <= 0, lance une InvalidOrderException.
    • Si la couleur de la commande est Color.BLACK, lance également une InvalidOrderException (couleur interdite).
  2. traiterProchaineCommande(LinkedList<Commande> fileCommandes, HashMap<String, Client> clients)

    • Utilise un Iterator<Commande> pour récupérer et retirer la première commande de la liste.
    • Valide la commande (quantité, prix, couleur) ; si invalide → InvalidOrderException.
    • Recherche le Client correspondant via clients.get(cmd.getClientId()) ;
      si le client n’existe pas → UnknownClientException.
    • Met à jour le solde du client : solde += quantite * prixUnitaire.
  3. supprimerCommandesInvalides(LinkedList<Commande> fileCommandes)

    • Parcourt la liste avec un Iterator<Commande>.
    • Supprime (iterator.remove()) les commandes invalides (quantité ou prix ≤ 0).
    • Si au moins une commande invalide a été supprimée, lance une InvalidOrderException contenant la dernière commande invalide supprimée.
  4. appliquerRemise(HashMap<String, Client> clients, double seuil, double remisePourcent)

    • Parcourt la HashMap à l’aide d’un Iterator<Map.Entry<String, Client>> ou d’un Iterator<Client>.
    • Pour chaque client dont le solde est ≥ seuil, applique une remise de remisePourcent % :
      nouveauSolde = solde * (1 - remisePourcent / 100)
    • Si le nouveau solde devient négatif, lance une NegativeBalanceException avec le client en erreur.
  5. trierCommandesParCouleur(LinkedList<Commande> commandes)

    • Trie la liste de commandes selon la couleur, avec l’ordre :
      • Noir > Rouge > Bleu > Jaune
    • Utilise un Comparator<Commande> dédié.

Comparator pour trier les commandes par couleur

  1. Créez une classe CommandeColorComparator qui implémente Comparator<Commande>.
  2. Implémentez la méthode compare(Commande c1, Commande c2) en utilisant une méthode interne getColorRank(Color color) qui renvoie un entier selon la priorité :
    • Color.BLACK → 4
    • Color.RED → 3
    • Color.BLUE → 2
    • Color.YELLOW → 1
    • autres couleurs → 0
  3. Intégrez ce comparateur dans OrderService.trierCommandesParCouleur.

Programme de test (Main)

Créez une classe Main qui :

  1. Initialise quelques Client dans une HashMap<String, Client> ;
  2. Initialise quelques Commande dans une LinkedList<Commande> avec différentes couleurs (Color.RED, Color.BLUE, Color.BLACK, Color.YELLOW) ;
  3. Appelle les méthodes de OrderService dans des blocs try/catch :
    • validerFileCommandes(...)
    • traiterProchaineCommande(...)
    • appliquerRemise(...)
    • trierCommandesParCouleur(...)
  4. Affiche les résultats et les erreurs en affichant également getObjectInError() pour mieux comprendre l’objet en cause.

Diagramme de classes (PlantUML)

Vous pouvez utiliser ce diagramme pour visualiser les relations entre les classes :

ModèleExceptionsService et logiqueApplicationClient-id : String-nom : String-solde : doubleCommande-id : String-clientId : String-description : String-quantite : int-prixUnitaire : double-color : ColorCollectionOperationException-objectInError : Object+getObjectInError() : ObjectInvalidOrderExceptionUnknownClientExceptionNegativeBalanceExceptionOrderService+validerFileCommandes(fileCommandes : LinkedList<Commande>) : void+traiterProchaineCommande(fileCommandes : LinkedList<Commande>, clients : HashMap<String, Client>) : void+supprimerCommandesInvalides(fileCommandes : LinkedList<Commande>) : void+appliquerRemise(clients : HashMap<String, Client>, seuil : double, remisePourcent : double) : void+trierCommandesParCouleur(commandes : LinkedList<Commande>) : voidComparatorT+compare(o1 : T, o2 : T) : intCommandeColorComparator+compare(c1 : Commande, c2 : Commande) : intMain+main(args : String[]) : void
ModèleExceptionsService et logiqueApplicationClient-id : String-nom : String-solde : doubleCommande-id : String-clientId : String-description : String-quantite : int-prixUnitaire : double-color : ColorCollectionOperationException-objectInError : Object+getObjectInError() : ObjectInvalidOrderExceptionUnknownClientExceptionNegativeBalanceExceptionOrderService+validerFileCommandes(fileCommandes : LinkedList<Commande>) : void+traiterProchaineCommande(fileCommandes : LinkedList<Commande>, clients : HashMap<String, Client>) : void+supprimerCommandesInvalides(fileCommandes : LinkedList<Commande>) : void+appliquerRemise(clients : HashMap<String, Client>, seuil : double, remisePourcent : double) : void+trierCommandesParCouleur(commandes : LinkedList<Commande>) : voidComparatorT+compare(o1 : T, o2 : T) : intCommandeColorComparator+compare(c1 : Commande, c2 : Commande) : intMain+main(args : String[]) : void