Menu
Coddy logo textTech

Système bancaire

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 89 sur 91.

challenge icon

Défi

Facile

Construisons 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 classe Transaction pour enregistrer les opérations financières. Utilisez la promotion de constructeur pour type (string — "deposit", "withdrawal", ou "transfer"), amount (float), et timestamp (string). Toutes les propriétés doivent être public readonly. Ajoutez une méthode getDescription(): string qui retourne "[type]: $[amount]" (formatez le montant à 2 décimales).
  • BankAccount.php — Incluez le fichier Transaction. Créez une classe abstraite BankAccount avec :
    • La promotion de constructeur pour accountNumber (string, public readonly) et holderName (string, public readonly)
    • Une propriété protégée $balance initialisée à 0.0
    • Un tableau privé pour stocker l'historique des transactions
    • getBalance(): float — retourne le solde actuel
    • deposit(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 retrait
    • addTransaction(Transaction $t): void — méthode protégée pour ajouter des transactions à l'historique
    • getTransactionCount(): int — retourne le nombre de transactions
  • SavingsAccount.php — Incluez le fichier BankAccount. Créez une classe SavingsAccount étendant BankAccount avec :
    • Une constante de classe INTEREST_RATE fixé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]"
  • CheckingAccount.php — Incluez le fichier BankAccount. Créez une classe CheckingAccount étendant BankAccount avec :
    • Une propriété privée $overdraftLimit dé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ès
    • getOverdraftLimit(): float — retourne la limite de découvert
  • Bank.php — Incluez les deux fichiers de compte. Créez une classe Bank qui gère les comptes :
    • Un tableau privé pour stocker les comptes indexés par numéro de compte
    • addAccount(BankAccount $account): void — ajoute un compte
    • findAccount(string $accountNumber): ?BankAccount — retourne le compte ou null
    • transfer(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 de deposit()
    • "withdraw" — Affiche le résultat de withdraw()
    • "transfer" — Affiche le résultat de transfer()
    • "interest" — Affiche le résultat de applyInterest() (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