Système bancaire
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 89 sur 91.
Défi
FacileConstruisons un Système Bancaire qui gère des comptes, des transactions et des transferts entre comptes. Vous allez créer un système avec une encapsulation appropriée pour protéger les données financières, l'héritage pour différents types de comptes et la validation pour garantir l'intégrité des données.
Vous organiserez votre code sur six fichiers :
Transaction.php— Créez une classeTransactionpour enregistrer les opérations financières. Utilisez la promotion de constructeur pourtype(string — "deposit", "withdrawal", ou "transfer"),amount(float), ettimestamp(string). Toutes les propriétés doivent être public readonly. Ajoutez une méthodegetDescription(): stringqui retourne"[type]: $[amount]"(formatez le montant à 2 décimales).BankAccount.php— Incluez le fichier Transaction. Créez une classe abstraiteBankAccountavec :- La promotion de constructeur pour
accountNumber(string, public readonly) etholderName(string, public readonly) - Une propriété protégée
$balanceinitialisée à 0.0 - Un tableau privé pour stocker l'historique des transactions
getBalance(): float— retourne le solde actueldeposit(float $amount): string— ajoute au solde, enregistre la transaction, retourne"Deposited: $[amount]"abstract withdraw(float $amount): string— les classes enfants implémentent les règles de retraitaddTransaction(Transaction $t): void— méthode protégée pour ajouter des transactions à l'historiquegetTransactionCount(): int— retourne le nombre de transactions
- La promotion de constructeur pour
SavingsAccount.php— Incluez le fichier BankAccount. Créez une classeSavingsAccountétendantBankAccountavec :- Une constante de classe
INTEREST_RATEfixée à 0.02 (2%) withdraw(float $amount): string— si le montant dépasse le solde, retourne"Insufficient funds"; sinon déduit, enregistre la transaction, retourne"Withdrew: $[amount]"applyInterest(): string— calcule les intérêts sur le solde actuel, les ajoute comme un dépôt, retourne"Interest applied: $[interest]"
- Une constante de classe
CheckingAccount.php— Incluez le fichier BankAccount. Créez une classeCheckingAccountétendantBankAccountavec :- Une propriété privée
$overdraftLimitdéfinie via le constructeur (ajoutez un troisième paramètre avec une valeur par défaut de 100.0) withdraw(float $amount): string— permet le retrait si le montant ne dépasse pas le solde + la limite de découvert ; retourne"Insufficient funds (overdraft limit: $[limit])"en cas d'échec, ou"Withdrew: $[amount]"en cas de succèsgetOverdraftLimit(): float— retourne la limite de découvert
- Une propriété privée
Bank.php— Incluez les deux fichiers de compte. Créez une classeBankqui gère les comptes :- Un tableau privé pour stocker les comptes indexés par numéro de compte
addAccount(BankAccount $account): void— ajoute un comptefindAccount(string $accountNumber): ?BankAccount— retourne le compte ou nulltransfer(string $fromAccount, string $toAccount, float $amount): string— transfère de l'argent entre les comptes. Retourne"Source account not found","Destination account not found", ou le résultat du retrait s'il échoue. En cas de succès, dépose sur la destination et retourne"Transferred $[amount] from [from] to [to]"
main.php— Incluez le fichier Bank. Vous recevrez deux entrées : les données des comptes (JSON) et les opérations (JSON).Format JSON des comptes :
[{"type": "savings", "number": "SAV001", "holder": "Alice", "initial": 1000}, {"type": "checking", "number": "CHK001", "holder": "Bob", "initial": 500, "overdraft": 200}]Format JSON des opérations :
[{"op": "deposit", "account": "SAV001", "amount": 200}, {"op": "withdraw", "account": "CHK001", "amount": 600}, {"op": "transfer", "from": "SAV001", "to": "CHK001", "amount": 300}, {"op": "interest", "account": "SAV001"}, {"op": "balance", "account": "SAV001"}]Créez la banque et tous les comptes (en déposant les montants initiaux). Traitez chaque opération :
"deposit"— Affiche le résultat dedeposit()"withdraw"— Affiche le résultat dewithdraw()"transfer"— Affiche le résultat detransfer()"interest"— Affiche le résultat deapplyInterest()(uniquement pour les comptes d'épargne)"balance"— Affiche"[holder] balance: $[balance]"(2 décimales)
Affichez chaque résultat sur une nouvelle ligne. Formatez tous les montants monétaires à 2 décimales.
N'oubliez pas que les transferts doivent être atomiques — si le retrait échoue, le dépôt ne doit pas avoir lieu. La propriété protégée $balance permet aux classes enfants de la modifier tout en la gardant cachée du code extérieur, démontrant une encapsulation appropriée dans un contexte financier.
Essayez vous-même
<?php
require_once 'Bank.php';
// Lire l'entrée
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));
// Analyser les entrées JSON
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);
// TODO: Créer une instance de Bank
// TODO: Créer des comptes à partir des données de comptes
// Pour chaque compte dans $accounts :
// - Si le type est "savings", créer SavingsAccount
// - Si le type est "checking", créer CheckingAccount (avec découvert si fourni)
// - Ajouter le compte à la banque
// - Déposer le montant initial
// TODO: Traiter chaque opération
// Pour chaque opération dans $operations :
// - "deposit": Afficher le résultat de deposit()
// - "withdraw": Afficher le résultat de withdraw()
// - "transfer": Afficher le résultat de transfer()
// - "interest": Afficher le résultat de applyInterest() (uniquement pour l'épargne)
// - "balance": Afficher "[holder] balance: $[balance]" (2 décimales)
?>Toutes les leçons de Programmation Orientée Objet
1Les bases de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition de méthodeLe mot-clé finalClasses abstraitesRécapitulatif - Hiérarchie des employés7Encapsulation
Public, Protégé, PrivéModificateurs d'accès en détailGetters et SettersMasquage d'informationPromotion de constructeur (8.0)Récapitulatif - Système de gestion d'étudiants10Concepts avancés de la POO
Composition vs HéritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibers (PHP 8.1)Clonage d'objets : analyse approfondieGénérateurs et Itérateurs13Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository2Espaces de noms et Autoloading
Introduction aux espaces de nomsLe mot-clé useStandard d'Autoloading PSR-4L'Autoloader ComposerRécapitulatif - Projet organisé5Interfaces et Contrats
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesInterface vs Classe AbstraiteType Hinting avec les InterfacesRécapitulatif - Calculateur de Formes8Méthodes magiques
Introduction aux méthodes magiques__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Clonage d'objets__serialize & __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d'instance vs Propriétés statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés readonly (PHP 8.1)Récapitulatif - Gestionnaire de compte bancaire6Polymorphisme
Retour sur la redéfinition de méthodePolymorphisme via les interfacesType Hinting et Types d'unionLiaison statique tardiveRécapitulatif - Processeur de paiement9Traits
Introduction aux TraitsUtilisation de plusieurs TraitsRésolution des conflits de TraitsMéthodes abstraites dans les TraitsTraits vs Héritage12Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie15Défis finaux
Plateforme d'E-LearningSystème bancaireDéveloppement de personnages de jeuService de location de véhicules