Système bancaire
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 104 sur 104.
Défi
FacileConstruisons un système bancaire qui illustre le patron de conception State (État), l'héritage et la gestion des pointeurs intelligents. Vous allez créer un système où les comptes peuvent être dans différents états (Active, Frozen, Closed), chacun ayant des comportements distincts pour la gestion des transactions.
Vous organiserez votre code sur six fichiers :
AccountState.h: Définissez l'infrastructure du patron State pour les états de compte.Créez une classe de base abstraite
AccountStateavec des méthodes virtuelles pures :deposit(double amount)— retourne true si le dépôt est autorisé, false sinonwithdraw(double amount)— retourne true si le retrait est autorisé, false sinongetStateName()— retourne le nom de l'état sous forme de chaîne de caractères
Implémentez trois états concrets :
ActiveState: Autorise à la fois les dépôts et les retraits, retourne"Active"FrozenState: Autorise les dépôts mais rejette les retraits, retourne"Frozen"ClosedState: Rejette à la fois les dépôts et les retraits, retourne"Closed"
Account.h: Construisez une hiérarchie de comptes avec gestion d'état.Créez une classe de base
Accountavec :- Un numéro de compte (chaîne), un nom de propriétaire et un solde
- Un
std::unique_ptr<AccountState>pour gérer l'état actuel deposit(double amount)— vérifie d'abord l'état, si autorisé ajoute au solde et affiche"Deposited [amount] to [accountNumber]", sinon affiche"Deposit rejected: account is [stateName]"withdraw(double amount)— vérifie l'état, si autorisé et fonds suffisants, déduit et affiche"Withdrew [amount] from [accountNumber]". Si l'état rejette, affiche"Withdrawal rejected: account is [stateName]". Si les fonds sont insuffisants, affiche"Insufficient funds"freeze(),activate()etclose()— changent l'état du comptegetInfo()— retourne"[accountNumber] ([ownerName]): $[balance] - [stateName]"- Une méthode virtuelle
getAccountType()retournant"Basic"
Créez deux types de comptes dérivés :
SavingsAccount: A une exigence de solde minimum (passée au constructeur). Surchargez withdraw pour vérifier également si le retrait ferait descendre le solde en dessous du minimum — si c'est le cas, affichez"Cannot go below minimum balance of [minimum]". Retourne"Savings"pour le type de compte.CheckingAccount: A une limite de découvert (passée au constructeur). Autorise les retraits jusqu'à (balance + overdraftLimit). Retourne"Checking"pour le type de compte.
Transaction.h: Modélisez les transactions comme des objets.Créez une classe
Transactionqui 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()retournant"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: Créez un client qui possède plusieurs comptes.Un
Customera un nom, un identifiant et un vecteur destd::shared_ptr<Account>. Implémentez :addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber)— retourne le compte correspondant ou nullptrgetTotalBalance()— additionne les soldes de tous les compteslistAccounts()— affiche les informations de chaque compte
Bank.h: Coordonnez les opérations bancaires.La classe
Bankstocke les clients et maintient un historique des transactions. Implémentez :addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber)— recherche le compte parmi tous les clientsprocessDeposit(const std::string& accountNumber, double amount)— trouve le compte, effectue le dépôt, enregistre la transactionprocessWithdrawal(const std::string& accountNumber, double amount)— trouve le compte, effectue le retrait, enregistre la transactiongetTransactionCount()— retourne le nombre total de transactions traitées
main.cpp: Démontrez votre système bancaire.Lisez quatre entrées :
- Détails du client (format :
name,customerId) - Détails du compte d'épargne (format :
accountNumber,minBalance) - Opération 1 (format :
action,accountNumber,amountoù action estdepositouwithdraw) - Opération 2 (format :
action,accountNumber,amountoufreeze,accountNumber)
Créez la banque et le client. Créez un compte d'épargne avec le client comme propriétaire 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 tentez un petit retrait de $10 pour démontrer l'état). Enfin, affichez la liste des comptes du client et le nombre total de transactions sous la forme
"Transactions: [count]".- Détails du client (format :
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: 2Avec 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: 2Avec 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: 2Ce défi réunit le patron State pour la gestion des comportements de compte, 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 des concepts fondamentaux que vous avez maîtrisés tout au long de ce cours.
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 à partir de customerInput
// Astuce : Utilisez find(',') pour diviser la chaîne
// TODO: Analyser les détails du compte à partir de 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 (l'action est "deposit" ou "withdraw")
// TODO: Analyser et traiter l'opération 2
// Peut être : action,accountNumber,amount OU freeze,accountNumber
// Si freeze, geler le compte puis tenter un retrait de $10
// TODO: Afficher la liste des comptes du client
// TODO: Afficher le nombre de transactions sous la forme "Transactions: [count]"
return 0;
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique