Sistema Bancário
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 104 de 104.
Desafio
FácilVamos 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
AccountStatecom métodos virtuais puros:deposit(double amount): retorna true se o depósito for permitido, false caso contráriowithdraw(double amount): retorna true se o saque for permitido, false caso contráriogetStateName(): 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
Accountcom:- 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()eclose(): alteram o estado da contagetInfo(): 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
Transactionque 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
Customertem um nome, um ID e um vetor destd::shared_ptr<Account>. Implemente:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber): retorna a conta correspondente ou nullptrgetTotalBalance(): soma os saldos de todas as contaslistAccounts(): imprime as informações de cada conta
Bank.h: Coordene as operações bancárias.A classe
Bankarmazena 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 clientesprocessDeposit(const std::string& accountNumber, double amount): encontra a conta, realiza o depósito e registra a transaçãoprocessWithdrawal(const std::string& accountNumber, double amount): encontra a conta, realiza o saque e registra a transaçãogetTransactionCount(): retorna o total de transações processadas
main.cpp: Demonstre seu sistema bancário.Leia quatro entradas:
- Detalhes do cliente (formato:
name,customerId) - Detalhes da conta poupança (formato:
accountNumber,minBalance) - Operação 1 (formato:
action,accountNumber,amount, em que action édepositouwithdraw) - Operação 2 (formato:
action,accountNumber,amountoufreeze,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]".- Detalhes do cliente (formato:
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: 2Com 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: 2Com 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: 2Este 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
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online