Menu
Coddy logo textTech

Système bancaire

Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 104 sur 104.

challenge icon

Défi

Facile

Construisons un système bancaire qui illustre le patron State, l’héritage et la gestion des pointeurs intelligents. Vous allez créer un système dans lequel les comptes peuvent se trouver dans différents états (Active, Frozen, Closed), chacun ayant des comportements distincts pour gérer les transactions.

Vous organiserez votre code sur six fichiers :

  • AccountState.h : définir l’infrastructure du patron State pour les états des comptes.

    Créez une classe de base abstraite AccountState avec des méthodes virtuelles pures :

    • deposit(double amount) : renvoie true si le dépôt est autorisé, false dans le cas contraire
    • withdraw(double amount) : renvoie true si le retrait est autorisé, false dans le cas contraire
    • getStateName() : renvoie le nom de l’état sous forme de chaîne

    Implémentez trois états concrets :

    • ActiveState : autorise les dépôts et les retraits, renvoie "Active"
    • FrozenState : autorise les dépôts mais refuse les retraits, renvoie "Frozen"
    • ClosedState : refuse les dépôts et les retraits, renvoie "Closed"
  • Account.h : construire une hiérarchie de comptes avec la gestion des états.

    Créez une classe de base Account avec :

    • Un numéro de compte (chaîne), le nom du titulaire et le solde
    • Un std::unique_ptr<AccountState> pour gérer l’état actuel
    • deposit(double amount) : vérifie d’abord l’état ; si le dépôt est autorisé, ajoute le montant au solde et affiche "Deposited [amount] to [accountNumber]" ; sinon, affiche "Deposit rejected: account is [stateName]"
    • withdraw(double amount) : vérifie l’état ; si le retrait est autorisé et les fonds suffisants, déduit le montant et affiche "Withdrew [amount] from [accountNumber]". Si l’état refuse le retrait, affiche "Withdrawal rejected: account is [stateName]". Si les fonds sont insuffisants, affiche "Insufficient funds"
    • freeze(), activate() et close() : modifient l’état du compte
    • getInfo() : renvoie "[accountNumber] ([ownerName]): $[balance] - [stateName]"
    • getAccountType() virtuelle renvoyant "Basic"

    Créez deux types de comptes dérivés :

    • SavingsAccount : possède une exigence de solde minimum (transmise au constructeur). Redéfinissez withdraw pour vérifier également si le retrait ferait passer le solde sous le minimum ; si c’est le cas, affichez "Cannot go below minimum balance of [minimum]". Renvoie "Savings" comme type de compte.
    • CheckingAccount : possède une limite de découvert (transmise au constructeur). Autorise les retraits jusqu’à (solde + overdraftLimit). Renvoie "Checking" comme type de compte.
  • Transaction.h : modéliser les transactions sous forme d’objets.

    Créez une classe Transaction qui enregistre :

    • Le type de transaction (chaîne : "Deposit", "Withdrawal", "Transfer")
    • Le montant
    • Le numéro de compte concerné
    • Le statut de réussite (bool)

    Ajoutez une méthode getDescription() renvoyant "[type]: $[amount] on [accountNumber] - [Success/Failed]"

  • Customer.h : créer un client qui possède plusieurs comptes.

    Un Customer possède un nom, un identifiant et un vecteur de std::shared_ptr<Account>. Implémentez :

    • addAccount(std::shared_ptr<Account> account)
    • getAccount(const std::string& accountNumber) : renvoie le compte correspondant ou nullptr
    • getTotalBalance() : additionne les soldes de tous les comptes
    • listAccounts() : affiche les informations de chaque compte
  • Bank.h : coordonner les opérations bancaires.

    La classe Bank stocke les clients et conserve un historique des transactions. Implémentez :

    • addCustomer(std::shared_ptr<Customer> customer)
    • findAccount(const std::string& accountNumber) : recherche le compte parmi tous les clients
    • processDeposit(const std::string& accountNumber, double amount) : trouve le compte, effectue le dépôt et enregistre la transaction
    • processWithdrawal(const std::string& accountNumber, double amount) : trouve le compte, effectue le retrait et enregistre la transaction
    • getTransactionCount() : renvoie le nombre total de transactions traitées
  • main.cpp : présenter votre système bancaire.

    Lisez quatre entrées :

    1. Informations du client (format : name,customerId)
    2. Informations du compte d’épargne (format : accountNumber,minBalance)
    3. Opération 1 (format : action,accountNumber,amount où action est deposit ou withdraw)
    4. Opération 2 (format : action,accountNumber,amount ou freeze,accountNumber)

    Créez la banque et le client. Créez un compte d’épargne dont le client est le titulaire et ajoutez-le au client. Ajoutez le client à la banque. Traitez les deux opérations (s’il s’agit d’une commande freeze, gelez le compte puis essayez d’effectuer un petit retrait de 10 $ pour illustrer l’état). Enfin, affichez la liste des comptes du client et le nombre total de transactions sous la forme "Transactions: [count]".

Par exemple, avec les entrées Alice,C001, SAV001,100, deposit,SAV001,500 et withdraw,SAV001,200 :

Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2

Avec les entrées Bob,C002, SAV002,50, deposit,SAV002,100 et freeze,SAV002 :

Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2

Avec les entrées Carol,C003, SAV003,200, deposit,SAV003,250 et withdraw,SAV003,100 :

Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2

Ce défi réunit le patron State pour gérer les comportements des comptes, l’héritage pour les différents types de comptes, les pointeurs intelligents pour les relations de propriété et le suivi des transactions : tous les concepts fondamentaux que vous avez maîtrisés au cours de cette formation.

Essayez vous-même

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"

int main() {
    // Lire l'entrée 1 : Détails du client (format : name,customerId)
    std::string customerInput;
    std::getline(std::cin, customerInput);
    
    // Lire l'entrée 2 : Détails du compte d'épargne (format : accountNumber,minBalance)
    std::string accountInput;
    std::getline(std::cin, accountInput);
    
    // Lire l'entrée 3 : Opération 1 (format : action,accountNumber,amount)
    std::string op1Input;
    std::getline(std::cin, op1Input);
    
    // Lire l'entrée 4 : Opération 2 (format : action,accountNumber,amount ou freeze,accountNumber)
    std::string op2Input;
    std::getline(std::cin, op2Input);
    
    // TODO: Analyser les détails du client depuis customerInput
    // Indice : Utiliser find(',') pour diviser la chaîne
    
    // TODO: Analyser les détails du compte depuis accountInput
    
    // TODO: Créer la banque
    
    // TODO: Créer le client
    
    // TODO: Créer un compte d'épargne avec le client comme propriétaire
    
    // TODO: Ajouter le compte au client
    
    // TODO: Ajouter le client à la banque
    
    // TODO: Analyser et traiter l'opération 1
    // Format : action,accountNumber,amount (action est "deposit" ou "withdraw")
    
    // TODO: Analyser et traiter l'opération 2
    // Pourrait être : action,accountNumber,amount OU freeze,accountNumber
    // Si freeze, geler le compte puis essayer un retrait de $10
    
    // TODO: Afficher la liste des comptes du client
    
    // TODO: Print transaction count as "Transactions: [count]"
    
    return 0;
}

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C++ en ligne