Menu
Coddy logo textTech

Sistema Bancário

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 89 de 91.

challenge icon

Desafio

Fácil

Vamos construir um Sistema Bancário que gerencia contas, transações e transferências entre contas. Você criará um sistema com encapsulamento adequado para proteger dados financeiros, herança para diferentes tipos de conta e validação para garantir a integridade dos dados.

Você organizará seu código em seis arquivos:

  • Transaction.php — Crie uma classe Transaction para registrar operações financeiras. Use a promoção de construtor para type (string — "deposit", "withdrawal", ou "transfer"), amount (float) e timestamp (string). Todas as propriedades devem ser public readonly. Adicione um método getDescription(): string que retorna "[type]: $[amount]" (formate o valor com 2 casas decimais).
  • BankAccount.php — Inclua o arquivo Transaction. Crie uma classe abstrata BankAccount com:
    • Promoção de construtor para accountNumber (string, public readonly) e holderName (string, public readonly)
    • Uma propriedade protegida $balance inicializada com 0.0
    • Um array privado para armazenar o histórico de transações
    • getBalance(): float — retorna o saldo atual
    • deposit(float $amount): string — adiciona ao saldo, registra a transação, retorna "Deposited: $[amount]"
    • abstract withdraw(float $amount): string — as classes filhas implementam as regras de saque
    • addTransaction(Transaction $t): void — método protegido para adicionar transações ao histórico
    • getTransactionCount(): int — retorna o número de transações
  • SavingsAccount.php — Inclua o arquivo BankAccount. Crie uma classe SavingsAccount estendendo BankAccount com:
    • Uma constante de classe INTEREST_RATE definida como 0.02 (2%)
    • withdraw(float $amount): string — se o valor exceder o saldo, retorne "Insufficient funds"; caso contrário, deduza, registre a transação e retorne "Withdrew: $[amount]"
    • applyInterest(): string — calcula os juros sobre o saldo atual, adiciona-os como um depósito e retorna "Interest applied: $[interest]"
  • CheckingAccount.php — Inclua o arquivo BankAccount. Crie uma classe CheckingAccount estendendo BankAccount com:
    • Uma propriedade privada $overdraftLimit definida via construtor (adicione um terceiro parâmetro com o padrão 100.0)
    • withdraw(float $amount): string — permite o saque se o valor não exceder o saldo + limite de cheque especial; retorne "Insufficient funds (overdraft limit: $[limit])" em caso de falha, ou "Withdrew: $[amount]" em caso de sucesso
    • getOverdraftLimit(): float — retorna o limite do cheque especial
  • Bank.php — Inclua ambos os arquivos de conta. Crie uma classe Bank que gerencia as contas:
    • Um array privado para armazenar contas indexadas pelo número da conta
    • addAccount(BankAccount $account): void — adiciona uma conta
    • findAccount(string $accountNumber): ?BankAccount — retorna a conta ou null
    • transfer(string $fromAccount, string $toAccount, float $amount): string — transfere dinheiro entre contas. Retorne "Source account not found", "Destination account not found", ou o resultado do saque se ele falhar. Em caso de sucesso, deposite no destino e retorne "Transferred $[amount] from [from] to [to]"
  • main.php — Inclua o arquivo Bank. Você receberá duas entradas: dados das contas (JSON) e operações (JSON).

    Formato JSON das Contas:

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

    Formato JSON das Operações:

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

    Crie o banco e todas as contas (depositando os valores iniciais). Processe cada operação:

    • "deposit" — Imprima o resultado de deposit()
    • "withdraw" — Imprima o resultado de withdraw()
    • "transfer" — Imprima o resultado de transfer()
    • "interest" — Imprima o resultado de applyInterest() (apenas para contas poupança)
    • "balance" — Imprima "[holder] balance: $[balance]" (2 casas decimais)

    Imprima cada resultado em uma nova linha. Formate todos os valores monetários com 2 casas decimais.

Lembre-se de que as transferências devem ser atômicas — se o saque falhar, o depósito não deve ocorrer. A propriedade protegida $balance permite que as classes filhas a modifiquem enquanto a mantêm oculta do código externo, demonstrando o encapsulamento adequado em um contexto financeiro.

Experimente você mesmo

<?php

require_once 'Bank.php';

// Ler a entrada
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));

// Analisar as entradas JSON
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);

// TODO: Criar uma instância de Bank

// TODO: Criar contas a partir dos dados das contas
// Para cada conta em $accounts:
//   - Se o tipo for "savings", criar SavingsAccount
//   - Se o tipo for "checking", criar CheckingAccount (com cheque especial se fornecido)
//   - Adicionar conta ao banco
//   - Depositar valor inicial

// TODO: Processar cada operação
// Para cada operação em $operations:
//   - "deposit": Imprimir resultado de deposit()
//   - "withdraw": Imprimir resultado de withdraw()
//   - "transfer": Imprimir resultado de transfer()
//   - "interest": Imprimir resultado de applyInterest() (apenas para poupança)
//   - "balance": Imprimir "[holder] balance: $[balance]" (2 casas decimais)

?>

Todas as lições de Programação Orientada a Objetos