Sistema bancario
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 104 de 104.
Desafío
FácilVamos a construir un Sistema Bancario que demuestre el patrón State, la herencia y la gestión de punteros inteligentes. Crearás un sistema donde las cuentas pueden estar en diferentes estados (Active, Frozen, Closed), cada uno con comportamientos distintos para manejar transacciones.
Organizarás tu código en seis archivos:
AccountState.h: Define la infraestructura del patrón State para los estados de la cuenta.Crea una clase base abstracta
AccountStatecon métodos virtuales puros:deposit(double amount)— devuelve true si el depósito está permitido, false en caso contrariowithdraw(double amount)— devuelve true si el retiro está permitido, false en caso contrariogetStateName()— devuelve el nombre del estado como un string
Implementa tres estados concretos:
ActiveState: Permite tanto depósitos como retiros, devuelve"Active"FrozenState: Permite depósitos pero rechaza retiros, devuelve"Frozen"ClosedState: Rechaza tanto depósitos como retiros, devuelve"Closed"
Account.h: Construye una jerarquía de cuentas con gestión de estados.Crea una clase base
Accountcon:- Número de cuenta (string), nombre del propietario y saldo
- Un
std::unique_ptr<AccountState>para gestionar el estado actual deposit(double amount)— consulta primero al estado; si está permitido, lo suma al saldo e imprime"Deposited [amount] to [accountNumber]", de lo contrario imprime"Deposit rejected: account is [stateName]"withdraw(double amount)— consulta al estado; si está permitido y hay fondos suficientes, deduce e imprime"Withdrew [amount] from [accountNumber]". Si el estado lo rechaza, imprime"Withdrawal rejected: account is [stateName]". Si no hay fondos suficientes, imprime"Insufficient funds"freeze(),activate()yclose()— cambian el estado de la cuentagetInfo()— devuelve"[accountNumber] ([ownerName]): $[balance] - [stateName]"getAccountType()virtual que devuelve"Basic"
Crea dos tipos de cuenta derivados:
SavingsAccount: Tiene un requisito de saldo mínimo (pasado al constructor). Sobrescribe withdraw para verificar también si el retiro caería por debajo del mínimo; si es así, imprime"Cannot go below minimum balance of [minimum]". Devuelve"Savings"como tipo de cuenta.CheckingAccount: Tiene un límite de sobregiro (pasado al constructor). Permite retiros hasta (balance + overdraftLimit). Devuelve"Checking"como tipo de cuenta.
Transaction.h: Modela las transacciones como objetos.Crea una clase
Transactionque registre:- Tipo de transacción (string: "Deposit", "Withdrawal", "Transfer")
- Monto
- Número de cuenta involucrado
- Estado de éxito (bool)
Añade un método
getDescription()que devuelva"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: Crea un cliente que posee múltiples cuentas.Un
Customertiene un nombre, ID y un vector destd::shared_ptr<Account>. Implementa:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber)— devuelve la cuenta coincidente o nullptrgetTotalBalance()— suma los saldos de todas las cuentaslistAccounts()— imprime la información de cada cuenta
Bank.h: Coordina las operaciones bancarias.La clase
Bankalmacena clientes y mantiene un historial de transacciones. Implementa:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber)— busca la cuenta en todos los clientesprocessDeposit(const std::string& accountNumber, double amount)— busca la cuenta, realiza el depósito, registra la transacciónprocessWithdrawal(const std::string& accountNumber, double amount)— busca la cuenta, realiza el retiro, registra la transaccióngetTransactionCount()— devuelve el total de transacciones procesadas
main.cpp: Demuestra tu sistema bancario.Lee cuatro entradas:
- Detalles del cliente (formato:
name,customerId) - Detalles de la cuenta de ahorros (formato:
accountNumber,minBalance) - Operación 1 (formato:
action,accountNumber,amountdonde action esdepositowithdraw) - Operación 2 (formato:
action,accountNumber,amountofreeze,accountNumber)
Crea el banco y el cliente. Crea una cuenta de ahorros con el cliente como propietario y añádela al cliente. Añade el cliente al banco. Procesa ambas operaciones (si es un comando freeze, congela la cuenta y luego intenta un pequeño retiro de $10 para demostrar el estado). Finalmente, imprime la lista de cuentas del cliente y el recuento total de transacciones como
"Transactions: [count]".- Detalles del cliente (formato:
Por ejemplo, con las entradas Alice,C001, SAV001,100, deposit,SAV001,500, y withdraw,SAV001,200:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2Con las entradas Bob,C002, SAV002,50, deposit,SAV002,100, y freeze,SAV002:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2Con las entradas Carol,C003, SAV003,200, deposit,SAV003,250, y withdraw,SAV003,100:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2Este desafío reúne el patrón State para gestionar los comportamientos de las cuentas, la herencia para diferentes tipos de cuentas, los punteros inteligentes para las relaciones de propiedad y el seguimiento de transacciones; todos conceptos básicos que has dominado a lo largo de este curso.
Pruébalo tú mismo
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// Leer entrada 1: Detalles del cliente (formato: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// Leer entrada 2: Detalles de la cuenta de ahorros (formato: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// Leer entrada 3: Operación 1 (formato: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// Leer entrada 4: Operación 2 (formato: action,accountNumber,amount o freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: Analizar los detalles del cliente desde customerInput
// Sugerencia: Usa find(',') para dividir la cadena
// TODO: Analizar los detalles de la cuenta desde accountInput
// TODO: Crear el banco
// TODO: Crear el cliente
// TODO: Crear una cuenta de ahorros con el cliente como propietario
// TODO: Añadir la cuenta al cliente
// TODO: Añadir el cliente al banco
// TODO: Analizar y procesar la operación 1
// Formato: action,accountNumber,amount (action es "deposit" o "withdraw")
// TODO: Analizar y procesar la operación 2
// Puede ser: action,accountNumber,amount O freeze,accountNumber
// Si es freeze, congelar la cuenta e intentar un retiro de $10
// TODO: Imprimir la lista de cuentas del cliente
// TODO: Imprimir el recuento de transacciones como "Transactions: [count]"
return 0;
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosConstrucción y compilación en C++Archivos de cabecera y archivos fuenteNamespaces y alcanceIntroducción a OOP en C++Clases vs ObjetosEl puntero 'this'Métodos (Funciones miembro)Atributos (Miembros de datos)Conceptos básicos de Ctors y DtorsResumen - Calculadora simple4Propiedades de clase
Miembros de instancia vs. estáticosGetters y SettersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases amigasResumen - Gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de Ctor y DtorSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualResumen - Jerarquía de empleados2Gestión de memoria
Memoria Stack vs HeapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Resumen - Gestor de arrays dinámicos5Encapsulamiento
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultamiento de informaciónStruct vs ClassClases anidadas e internasResumen - Sistema de registros de estudiantes8Polimorfismo
Polimorfismo: Compilación vs. Tiempo de ejecuciónSobrecarga de funcionesFunciones virtuales revisadasFunciones virtuales purasClases abstractasDiseño de interfaces en C++Dynamic Casting y RTTIResumen: Calculadora de figuras11Conceptos avanzados de POO
Composición vs. HerenciaMixins mediante CRTPIdioma PimplBorrado de tiposEnum Classes y tipado fuerteManejo de excepciones en POOJerarquías de excepciones personalizadas14Patrones de diseño - Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositeRAII como patrón3Constructores y Destructores
Constructor por defectoConstructor parametrizadoConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis profundo del destructorRegla de tres / cinco / ceroResumen - Clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujo (Stream)Sobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tiposResumen - Clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasConceptos básicos de SFINAE y Type TraitsResumen - Contenedor genérico