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 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
AccountStateavec des méthodes virtuelles pures :deposit(double amount): renvoie true si le dépôt est autorisé, false dans le cas contrairewithdraw(double amount): renvoie true si le retrait est autorisé, false dans le cas contrairegetStateName(): 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
Accountavec :- 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()etclose(): modifient l’état du comptegetInfo(): 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
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()renvoyant"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: créer un client qui possède plusieurs comptes.Un
Customerpossède un nom, un identifiant et un vecteur destd::shared_ptr<Account>. Implémentez :addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber): renvoie le compte correspondant ou nullptrgetTotalBalance(): additionne les soldes de tous les compteslistAccounts(): affiche les informations de chaque compte
Bank.h: coordonner les opérations bancaires.La classe
Bankstocke 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 clientsprocessDeposit(const std::string& accountNumber, double amount): trouve le compte, effectue le dépôt et enregistre la transactionprocessWithdrawal(const std::string& accountNumber, double amount): trouve le compte, effectue le retrait et enregistre la transactiongetTransactionCount(): renvoie le nombre total de transactions traitées
main.cpp: présenter votre système bancaire.Lisez quatre entrées :
- Informations du client (format :
name,customerId) - Informations 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 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]".- Informations 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 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
1Fondamentaux de la POO
Fichiers externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents 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 de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des 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 des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne