Menu
Coddy logo textTech

Sistema Bancário

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 104 de 104.

challenge icon

Desafio

Fácil

Vamos criar um Sistema Bancário que demonstra o padrão State, herança e gerenciamento de ponteiros inteligentes. Você criará um sistema no qual as contas podem estar em diferentes estados (Active, Frozen, Closed), cada um com comportamentos distintos para lidar com transações.

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

  • AccountState.h: Defina a infraestrutura do padrão State para os estados das contas.

    Crie uma classe base abstrata AccountState com métodos virtuais puros:

    • deposit(double amount): retorna true se o depósito for permitido, false caso contrário
    • withdraw(double amount): retorna true se o saque for permitido, false caso contrário
    • getStateName(): retorna o nome do estado como uma string

    Implemente três estados concretos:

    • ActiveState: Permite depósitos e saques, retorna "Active"
    • FrozenState: Permite depósitos, mas rejeita saques, retorna "Frozen"
    • ClosedState: Rejeita depósitos e saques, retorna "Closed"
  • Account.h: Crie uma hierarquia de contas com gerenciamento de estados.

    Crie uma classe base Account com:

    • Número da conta (string), nome do titular e saldo
    • Um std::unique_ptr<AccountState> para gerenciar o estado atual
    • deposit(double amount): verifica primeiro com o estado; se permitido, adiciona ao saldo e imprime "Deposited [amount] to [accountNumber]"; caso contrário, imprime "Deposit rejected: account is [stateName]"
    • withdraw(double amount): verifica com o estado; se permitido e houver fundos suficientes, deduz o valor e imprime "Withdrew [amount] from [accountNumber]". Se o estado rejeitar, imprime "Withdrawal rejected: account is [stateName]". Se não houver fundos suficientes, imprime "Insufficient funds"
    • freeze(), activate() e close(): alteram o estado da conta
    • getInfo(): retorna "[accountNumber] ([ownerName]): $[balance] - [stateName]"
    • getAccountType() virtual, retornando "Basic"

    Crie dois tipos de conta derivados:

    • SavingsAccount: Possui um requisito de saldo mínimo (passado ao construtor). Sobrescreva withdraw para também verificar se o saque faria o saldo ficar abaixo do mínimo; em caso afirmativo, imprima "Cannot go below minimum balance of [minimum]". Retorna "Savings" como tipo de conta.
    • CheckingAccount: Possui um limite de cheque especial (passado ao construtor). Permite saques de até (saldo + overdraftLimit). Retorna "Checking" como tipo de conta.
  • Transaction.h: Modele transações como objetos.

    Crie uma classe Transaction que registre:

    • Tipo de transação (string: "Deposit", "Withdrawal", "Transfer")
    • Valor
    • Número da conta envolvida
    • Status de sucesso (bool)

    Adicione um método getDescription() que retorne "[type]: $[amount] on [accountNumber] - [Success/Failed]"

  • Customer.h: Crie um cliente que possua várias contas.

    Um Customer tem um nome, um ID e um vetor de std::shared_ptr<Account>. Implemente:

    • addAccount(std::shared_ptr<Account> account)
    • getAccount(const std::string& accountNumber): retorna a conta correspondente ou nullptr
    • getTotalBalance(): soma os saldos de todas as contas
    • listAccounts(): imprime as informações de cada conta
  • Bank.h: Coordene as operações bancárias.

    A classe Bank armazena clientes e mantém um histórico de transações. Implemente:

    • addCustomer(std::shared_ptr<Customer> customer)
    • findAccount(const std::string& accountNumber): pesquisa a conta entre todos os clientes
    • processDeposit(const std::string& accountNumber, double amount): encontra a conta, realiza o depósito e registra a transação
    • processWithdrawal(const std::string& accountNumber, double amount): encontra a conta, realiza o saque e registra a transação
    • getTransactionCount(): retorna o total de transações processadas
  • main.cpp: Demonstre seu sistema bancário.

    Leia quatro entradas:

    1. Detalhes do cliente (formato: name,customerId)
    2. Detalhes da conta poupança (formato: accountNumber,minBalance)
    3. Operação 1 (formato: action,accountNumber,amount, em que action é deposit ou withdraw)
    4. Operação 2 (formato: action,accountNumber,amount ou freeze,accountNumber)

    Crie o banco e o cliente. Crie uma conta poupança tendo o cliente como titular e adicione-a ao cliente. Adicione o cliente ao banco. Processe ambas as operações (se for um comando de congelamento, congele a conta e tente então um pequeno saque de $10 para demonstrar o estado). Por fim, imprima a lista de contas do cliente e o total de transações como "Transactions: [count]".

Por exemplo, com as entradas Alice,C001, SAV001,100, deposit,SAV001,500 e withdraw,SAV001,200:

Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2

Com as entradas Bob,C002, SAV002,50, deposit,SAV002,100 e freeze,SAV002:

Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2

Com as entradas Carol,C003, SAV003,200, deposit,SAV003,250 e withdraw,SAV003,100:

Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2

Este desafio reúne o padrão State para gerenciar comportamentos de contas, herança para diferentes tipos de conta, ponteiros inteligentes para relações de propriedade e rastreamento de transações: todos conceitos fundamentais que você dominou ao longo deste curso.

Experimente você mesmo

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"

int main() {
    // Ler entrada 1: Detalhes do cliente (formato: name,customerId)
    std::string customerInput;
    std::getline(std::cin, customerInput);
    
    // Ler entrada 2: Detalhes da conta poupança (formato: accountNumber,minBalance)
    std::string accountInput;
    std::getline(std::cin, accountInput);
    
    // Ler entrada 3: Operação 1 (formato: action,accountNumber,amount)
    std::string op1Input;
    std::getline(std::cin, op1Input);
    
    // Ler entrada 4: Operação 2 (formato: action,accountNumber,amount ou freeze,accountNumber)
    std::string op2Input;
    std::getline(std::cin, op2Input);
    
    // TODO: Analisar os detalhes do cliente a partir de customerInput
    // Dica: Use find(',') para dividir a string
    
    // TODO: Analisar os detalhes da conta a partir de accountInput
    
    // TODO: Criar o banco
    
    // TODO: Criar o cliente
    
    // TODO: Criar uma conta poupança com o cliente como proprietário
    
    // TODO: Adicionar a conta ao cliente
    
    // TODO: Adicionar o cliente ao banco
    
    // TODO: Analisar e processar a operação 1
    // Formato: action,accountNumber,amount (action é "deposit" ou "withdraw")
    
    // TODO: Analisar e processar a operação 2
    // Pode ser: action,accountNumber,amount OU freeze,accountNumber
    // Se freeze, congele a conta e então tente um saque de $10
    
    // TODO: Imprima a lista de contas do cliente
    
    // TODO: Print transaction count as "Transactions: [count]"
    
    return 0;
}

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

Pratique por conta própria: Compilador de C++ online