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 criar 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 propriedades no construtor para type (string: "deposit", "withdrawal" ou "transfer"), amount (float) e timestamp (string). Todas as propriedades devem ser públicas e somente para leitura. Adicione um método getDescription(): string que retorne "[type]: $[amount]" (formate o valor para 2 casas decimais).
  • BankAccount.php: Inclua o arquivo Transaction. Crie uma classe abstrata BankAccount com:
    • Promoção de propriedades no construtor para accountNumber (string, pública e somente para leitura) e holderName (string, pública e somente para leitura)
    • Uma propriedade $balance protegida, inicializada como 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 e 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 que estenda 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, desconte o valor, 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 que estenda BankAccount com:
    • Uma propriedade $overdraftLimit privada, definida por meio do construtor (adicione um terceiro parâmetro com valor padrão 100.0)
    • withdraw(float $amount): string: permite o saque se o valor não exceder o saldo + o 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 de cheque especial
  • Bank.php: Inclua ambos os arquivos de conta. Crie uma classe Bank que gerencie as contas:
    • Um array privado para armazenar as 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 na conta de 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 do JSON das contas:

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

    Formato do 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() (somente 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 acontecer. A propriedade protegida $balance permite que as classes filhas a modifiquem, mantendo-a oculta do código externo e demonstrando o encapsulamento adequado em um contexto financeiro.

Experimente você mesmo

<?php

require_once 'Bank.php';

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

// Analisar 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 de accounts
// Para cada conta em $accounts:
//   - Se o tipo for "savings", criar SavingsAccount
//   - Se o tipo for "checking", criar CheckingAccount (com overdraft se fornecido)
//   - Adicionar conta ao bank
//   - Depositar o valor inicial

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

?>

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

Pratique por conta própria: Compilador de PHP online