Menu
Coddy logo textTech

Sistema bancario

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 89 di 91.

challenge icon

Sfida

Facile

Creiamo un Sistema bancario che gestisce conti, transazioni e trasferimenti tra conti. Creerai un sistema con un corretto incapsulamento per proteggere i dati finanziari, ereditarietà per i diversi tipi di conto e convalida per garantire l'integrità dei dati.

Organizzerai il codice in sei file:

  • Transaction.php: crea una classe Transaction per registrare le operazioni finanziarie. Usa la promozione dei parametri del costruttore per type (stringa: "deposit", "withdrawal" o "transfer"), amount (float) e timestamp (stringa). Tutte le proprietà devono essere public readonly. Aggiungi un metodo getDescription(): string che restituisce "[type]: $[amount]" (formatta l'importo con 2 cifre decimali).
  • BankAccount.php: includi il file Transaction. Crea una classe astratta BankAccount con:
    • Promozione dei parametri del costruttore per accountNumber (stringa, public readonly) e holderName (stringa, public readonly)
    • Una proprietà protetta $balance inizializzata a 0.0
    • Un array privato per memorizzare la cronologia delle transazioni
    • getBalance(): float: restituisce il saldo corrente
    • deposit(float $amount): string: aggiunge l'importo al saldo, registra la transazione e restituisce "Deposited: $[amount]"
    • abstract withdraw(float $amount): string: le classi figlie implementano le regole di prelievo
    • addTransaction(Transaction $t): void: metodo protetto per aggiungere transazioni alla cronologia
    • getTransactionCount(): int: restituisce il numero di transazioni
  • SavingsAccount.php: includi il file BankAccount. Crea una classe SavingsAccount che estende BankAccount con:
    • Una costante di classe INTEREST_RATE impostata a 0.02 (2%)
    • withdraw(float $amount): string: se l'importo supera il saldo, restituisce "Insufficient funds"; altrimenti lo sottrae, registra la transazione e restituisce "Withdrew: $[amount]"
    • applyInterest(): string: calcola gli interessi sul saldo corrente, li aggiunge come deposito e restituisce "Interest applied: $[interest]"
  • CheckingAccount.php: includi il file BankAccount. Crea una classe CheckingAccount che estende BankAccount con:
    • Una proprietà privata $overdraftLimit impostata tramite il costruttore (aggiungi un terzo parametro con valore predefinito 100.0)
    • withdraw(float $amount): string: consente il prelievo se l'importo non supera il saldo + il limite di scoperto; in caso di errore restituisce "Insufficient funds (overdraft limit: $[limit])", altrimenti restituisce "Withdrew: $[amount]"
    • getOverdraftLimit(): float: restituisce il limite di scoperto
  • Bank.php: includi entrambi i file dei conti. Crea una classe Bank che gestisce i conti:
    • Un array privato per memorizzare i conti indicizzati per numero di conto
    • addAccount(BankAccount $account): void: aggiunge un conto
    • findAccount(string $accountNumber): ?BankAccount: restituisce il conto oppure null
    • transfer(string $fromAccount, string $toAccount, float $amount): string: trasferisce denaro tra conti. Restituisce "Source account not found", "Destination account not found" oppure il risultato del prelievo se non va a buon fine. In caso di successo, deposita l'importo sul conto destinatario e restituisce "Transferred $[amount] from [from] to [to]"
  • main.php: includi il file Bank. Riceverai due input: i dati dei conti (JSON) e le operazioni (JSON).

    Formato JSON dei conti:

    [{"type": "savings", "number": "SAV001", "holder": "Alice", "initial": 1000}, {"type": "checking", "number": "CHK001", "holder": "Bob", "initial": 500, "overdraft": 200}]

    Formato JSON delle operazioni:

    [{"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"}]

    Crea la banca e tutti i conti (versando gli importi iniziali). Elabora ogni operazione:

    • "deposit": stampa il risultato di deposit()
    • "withdraw": stampa il risultato di withdraw()
    • "transfer": stampa il risultato di transfer()
    • "interest": stampa il risultato di applyInterest() (solo per i conti di risparmio)
    • "balance": stampa "[holder] balance: $[balance]" (2 cifre decimali)

    Stampa ogni risultato su una nuova riga. Formatta tutti gli importi monetari con 2 cifre decimali.

Ricorda che i trasferimenti devono essere atomici: se il prelievo non va a buon fine, il deposito non deve avvenire. La proprietà protetta $balance consente alle classi figlie di modificarla mantenendola nascosta al codice esterno, dimostrando un corretto incapsulamento in un contesto finanziario.

Provalo tu

<?php

require_once 'Bank.php';

// Leggi l'input
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));

// Analizza gli input JSON
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);

// TODO: Crea un'istanza di Bank

// TODO: Crea gli account dai dati degli account
// Per ogni account in $accounts:
//   - Se type è "savings", crea SavingsAccount
//   - Se type è "checking", crea CheckingAccount (con scoperto, se fornito)
//   - Aggiungi l'account alla banca
//   - Deposita l'importo iniziale

// TODO: Elabora ogni operazione
// Per ogni operazione in $operations:
//   - "deposit": Stampa il risultato di deposit()
//   - "withdraw": stampa il risultato di withdraw()
//   - "transfer": stampa il risultato di transfer()
//   - "interest": stampa il risultato di applyInterest() (solo per i conti di risparmio)
//   - "balance": stampa "[holder] balance: $[balance]" (con 2 cifre decimali)

?>

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online