Skip to content

Exceptions - Système de réservation

Objectif

Créer un système de réservation pour un théâtre qui gère différentes exceptions (places insuffisantes, réservation déjà existante, etc.) en utilisant des exceptions personnalisées.

Contexte

Vous allez concevoir un système de réservation de sièges pour un théâtre.

import java.util.HashMap;
import java.util.Map;

class PlacesInsuffisantesException extends Exception {
    public PlacesInsuffisantesException(String message) {
        super(message);
    }
}

class ReservationExistanteException extends Exception {
    public ReservationExistanteException(String message) {
        super(message);
    }
}

class Reservation {
    private String nomClient;

    public Reservation(String nomClient) {
        this.nomClient = nomClient;
    }

    @Override
    public String toString() {
        return nomClient;
    }
}

public class Theatre {
    private Reservation[] reservations;
    private int capacite;

    // Constructeur
    public Theatre(int capacite) {
        this.capacite = capacite;
        this.reservations = new Reservation[capacite];
    }

    // Méthode de réservation
    public void reserver(int numeroPlace, String nomClient) throws PlacesInsuffisantesException, ReservationExistanteException {
        int count = 0;
        for (Reservation reservation : reservations) {
            if (reservation != null) {
                count++;
            }
        }
        if (count >= capacite) {
            throw new PlacesInsuffisantesException("Toutes les places sont réservées. Capacité atteinte : " + capacite);
        }
        if (numeroPlace < 1 || numeroPlace > capacite || reservations[numeroPlace - 1] != null) {
            throw new ReservationExistanteException("La place " + numeroPlace + " est déjà réservée.");
        }
        reservations[numeroPlace - 1] = new Reservation(nomClient);
        System.out.println("Réservation effectuée pour le client " + nomClient + " à la place " + numeroPlace);
    }

    // Méthode pour annuler une réservation
    public void annulerReservation(int numeroPlace) throws ReservationExistanteException {
        if (numeroPlace < 1 || numeroPlace > capacite || reservations[numeroPlace - 1] == null) {
            throw new ReservationExistanteException("La place " + numeroPlace + " n'est pas réservée.");
        }
        reservations[numeroPlace - 1] = null;
        System.out.println("Réservation annulée pour la place " + numeroPlace);
    }

    // Main pour tester
    public static void main(String[] args) {
        Theatre theatre = new Theatre(3);
        try {
            theatre.reserver(1, "Alice");
            theatre.reserver(2, "Bob");
            theatre.reserver(3, "Charlie");
            theatre.annulerReservation(2);
            theatre.reserver(2, "David");
            theatre.reserver(4, "Eve"); // Cela devrait déclencher une exception
        } catch (PlacesInsuffisantesException | ReservationExistanteException e) {
            System.out.println("Erreur : " + e.getMessage());
        }
    }
}

Tâche pour l'Exercice 3

  1. Créez une classe nommée Theatre qui permet de gérer des réservations de places. Chaque réservation doit être représentée par un objet de type Reservation.
  2. Implémentez le constructeur Theatre(int capacite) qui initialise la capacité du théâtre et un tableau pour stocker les réservations.
  3. Ajoutez une méthode reserver(int numeroPlace, String nomClient) qui permet de réserver une place spécifique pour un client. Si la place est déjà réservée ou si la capacité est atteinte, lancez les exceptions appropriées.
  4. Ajoutez une méthode annulerReservation(int numeroPlace) pour annuler une réservation existante. Lancez une exception si la place n'est pas réservée.
  5. Testez votre code dans la méthode main en ajoutant et en annulant des réservations pour vérifier le bon fonctionnement des exceptions.

Diagramme UML pour l'Exercice 3 (PlantUML)

TheatreReservation[] reservationsint capaciteTheatre(int capacite)reserver(int numeroPlace, String nomClient)annulerReservation(int numeroPlace)ReservationString nomClientReservation(String nomClient)toString(): StringPlacesInsuffisantesExceptionReservationExistanteException1manyuseuse
TheatreReservation[] reservationsint capaciteTheatre(int capacite)reserver(int numeroPlace, String nomClient)annulerReservation(int numeroPlace)ReservationString nomClientReservation(String nomClient)toString(): StringPlacesInsuffisantesExceptionReservationExistanteException1manyuseuse

Exercice 4 : Gestion des transactions avec rollback en cas d'erreur

Objectif

Simuler une transaction bancaire entre deux comptes avec la possibilité d'annuler la transaction en cas d'erreur (par exemple, fonds insuffisants). Utiliser des exceptions pour gérer les erreurs et implémenter une fonctionnalité de rollback.

import java.util.ArrayList;
import java.util.List;

class TransactionException extends Exception {
    public TransactionException(String message) {
        super(message);
    }
}

class HistoriquePleinException extends Exception {
    public HistoriquePleinException(String message) {
        super(message);
    }
}

class HistoriqueTransaction {
    private String description;

    public HistoriqueTransaction(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return description;
    }
}

public class TransactionBancaire {
    private double solde;
    private HistoriqueTransaction[] historique;

    // Constructeur
    public TransactionBancaire(double soldeInitial) {
        this.solde = soldeInitial;
        this.historique = new HistoriqueTransaction[10];
    }

    // Méthode de transfert
    public void transferer(TransactionBancaire destination, double montant) throws TransactionException, HistoriquePleinException {
        if (montant > this.solde) {
            throw new TransactionException("Fonds insuffisants pour la transaction. Solde actuel : " + this.solde);
        }

        // Début de la transaction
        this.solde -= montant;
        destination.solde += montant;

        String transactionDetails = "Transféré " + montant + " de " + this + " à " + destination;
        int count = 0;
        for (HistoriqueTransaction transaction : historique) {
            if (transaction != null) {
                count++;
            }
        }
        if (count >= 10) {
            throw new HistoriquePleinException("Historique des transactions plein. Impossible d'ajouter une nouvelle transaction.");
        }
        for (int i = 0; i < historique.length; i++) {
            if (historique[i] == null) {
                historique[i] = new HistoriqueTransaction(transactionDetails);
                break;
            }
        }
        destination.ajouterHistorique(transactionDetails);

        System.out.println("Transaction réussie. Solde source : " + this.solde + ", Solde destination : " + destination.solde);
    }

    // Méthode pour ajouter l'historique
    private void ajouterHistorique(String description) {
        for (int i = 0; i < historique.length; i++) {
            if (historique[i] == null) {
                historique[i] = new HistoriqueTransaction(description);
                break;
            }
        }
    }

    // Méthode pour afficher l'historique des transactions
    public void afficherHistorique() {
        System.out.println("Historique des transactions :");
        for (HistoriqueTransaction transaction : historique) {
            System.out.println(transaction);
        }
    }

    // Main pour tester
    public static void main(String[] args) {
        TransactionBancaire compteA = new TransactionBancaire(500);
        TransactionBancaire compteB = new TransactionBancaire(300);

        try {
            compteA.transferer(compteB, 200);
            compteA.transferer(compteB, 400); // Cela devrait déclencher une exception
        } catch (TransactionException e) {
            System.out.println("Erreur de transaction : " + e.getMessage());
            // Rollback - Annuler la dernière transaction
            compteA.solde += 200;
            compteB.solde -= 200;
            System.out.println("Rollback effectué. Solde source : " + compteA.solde + ", Solde destination : " + compteB.solde);
        } catch (HistoriquePleinException e) {
            System.out.println("Erreur d'historique : " + e.getMessage());
        }

        // Afficher l'historique des transactions
        compteA.afficherHistorique();
        compteB.afficherHistorique();
    }
}

Tâche pour l'Exercice 4

  1. Créez une classe nommée TransactionBancaire qui permet de gérer les transactions entre deux comptes.
  2. Implémentez le constructeur TransactionBancaire(double soldeInitial) qui initialise le solde et un tableau pour enregistrer l'historique des transactions.
  3. Ajoutez une méthode transferer(TransactionBancaire destination, double montant) qui permet de transférer un montant d'un compte à un autre. Si le solde est insuffisant, annuler l'opération et lancez une exception TransactionException.
  4. Si l'historique dépasse 10 enregistrements, lancez une exception HistoriquePleinException.
  5. Ajoutez une méthode afficherHistorique() pour afficher toutes les transactions effectuées.
  6. Testez votre code dans la méthode main en réalisant des transferts entre deux comptes et en vérifiant la bonne gestion des erreurs et de l'historique.

Diagramme UML pour l'Exercice 4 (PlantUML)

TransactionBancairedouble soldeHistoriqueTransaction[] historiqueTransactionBancaire(double soldeInitial)transferer(TransactionBancaire destination, double montant)afficherHistorique()HistoriqueTransactionString descriptionHistoriqueTransaction(String description)toString(): StringTransactionExceptionHistoriquePleinException1manyuseuse
TransactionBancairedouble soldeHistoriqueTransaction[] historiqueTransactionBancaire(double soldeInitial)transferer(TransactionBancaire destination, double montant)afficherHistorique()HistoriqueTransactionString descriptionHistoriqueTransaction(String description)toString(): StringTransactionExceptionHistoriquePleinException1manyuseuse