은행 시스템
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 104번째.
챌린지
쉬움State 패턴, 상속, 스마트 포인터 관리를 보여 주는 Banking System을 만들어 봅시다. 트랜잭션을 처리하는 동작이 각각 다른 여러 상태(Active, Frozen, Closed)에 있을 수 있는 계정 시스템을 만들게 됩니다.
코드를 다음 여섯 개 파일로 구성합니다:
AccountState.h: 계정 상태를 위한 State 패턴 인프라를 정의합니다.순수 가상 메서드를 포함하는 추상
AccountState기본 클래스를 만듭니다:deposit(double amount): 입금이 허용되면 true를, 그렇지 않으면 false를 반환합니다withdraw(double amount): 출금이 허용되면 true를, 그렇지 않으면 false를 반환합니다getStateName(): 상태 이름을 문자열로 반환합니다
세 가지 구체적인 상태를 구현합니다:
ActiveState: 입금과 출금을 모두 허용하며"Active"를 반환합니다FrozenState: 입금은 허용하지만 출금은 거부하며"Frozen"을 반환합니다ClosedState: 입금과 출금을 모두 거부하며"Closed"를 반환합니다
Account.h: 상태 관리를 포함하는 계정 계층 구조를 만듭니다.다음 요소를 포함하는 기본
Account클래스를 만듭니다:- 계정 번호(string), 소유자 이름, 잔액
- 현재 상태를 관리하기 위한
std::unique_ptr<AccountState> deposit(double amount): 먼저 상태를 확인하고, 허용되면 잔액에 더한 뒤"Deposited [amount] to [accountNumber]"를 출력합니다. 그렇지 않으면"Deposit rejected: account is [stateName]"을 출력합니다withdraw(double amount): 상태를 확인하고, 허용되며 잔액이 충분하면 금액을 차감한 뒤"Withdrew [amount] from [accountNumber]"를 출력합니다. 상태가 거부하면"Withdrawal rejected: account is [stateName]"을 출력합니다. 잔액이 부족하면"Insufficient funds"를 출력합니다freeze(),activate(),close(): 계정 상태를 변경합니다getInfo():"[accountNumber] ([ownerName]): $[balance] - [stateName]"을 반환합니다"Basic"을 반환하는 가상getAccountType()
두 가지 파생 계정 유형을 만듭니다:
SavingsAccount: 최소 잔액 요구 사항이 있습니다(생성자에 전달). 출금으로 인해 최소 잔액 아래로 내려가는지도 확인하도록 withdraw를 재정의하고, 그런 경우"Cannot go below minimum balance of [minimum]"을 출력합니다. 계정 유형으로"Savings"를 반환합니다.CheckingAccount: 초과 인출 한도가 있습니다(생성자에 전달). (잔액 + overdraftLimit)까지 출금을 허용합니다. 계정 유형으로"Checking"을 반환합니다.
Transaction.h: 트랜잭션을 객체로 모델링합니다.다음 정보를 기록하는
Transaction클래스를 만듭니다:- 트랜잭션 유형(string: "Deposit", "Withdrawal", "Transfer")
- 금액
- 관련 계정 번호
- 성공 상태(bool)
"[type]: $[amount] on [accountNumber] - [Success/Failed]"를 반환하는getDescription()메서드를 추가합니다Customer.h: 여러 계정을 소유하는 고객을 만듭니다.Customer는 이름, ID, 그리고std::shared_ptr<Account>의 vector를 가집니다. 다음을 구현합니다:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber): 일치하는 계정을 반환하거나 nullptr을 반환합니다getTotalBalance(): 모든 계정의 잔액을 합산합니다listAccounts(): 각 계정의 정보를 출력합니다
Bank.h: 은행 업무를 조정합니다.Bank클래스는 고객을 저장하고 트랜잭션 기록을 유지합니다. 다음을 구현합니다:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber): 모든 고객을 검색하여 계정을 찾습니다processDeposit(const std::string& accountNumber, double amount): 계정을 찾고, 입금을 수행하며, 트랜잭션을 기록합니다processWithdrawal(const std::string& accountNumber, double amount): 계정을 찾고, 출금을 수행하며, 트랜잭션을 기록합니다getTransactionCount(): 처리된 전체 트랜잭션 수를 반환합니다
main.cpp: Banking System을 시연합니다.네 가지 입력을 읽습니다:
- 고객 정보(형식:
name,customerId) - 저축 계정 정보(형식:
accountNumber,minBalance) - 작업 1(형식:
action,accountNumber,amount, 여기서 action은deposit또는withdraw입니다) - 작업 2(형식:
action,accountNumber,amount또는freeze,accountNumber)
은행과 고객을 만듭니다. 고객을 소유자로 하는 저축 계정을 만들고 고객에게 추가합니다. 고객을 은행에 추가합니다. 두 작업을 처리합니다(freeze 명령인 경우 계정을 동결한 다음 상태를 보여 주기 위해 $10을 소액 출금합니다). 마지막으로 고객의 계정 목록과 전체 트랜잭션 수를
"Transactions: [count]"형식으로 출력합니다.- 고객 정보(형식:
예를 들어 입력이 Alice,C001, SAV001,100, deposit,SAV001,500, withdraw,SAV001,200인 경우:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2입력이 Bob,C002, SAV002,50, deposit,SAV002,100, freeze,SAV002인 경우:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2입력이 Carol,C003, SAV003,200, deposit,SAV003,250, withdraw,SAV003,100인 경우:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2이 challenge에서는 계정 동작을 관리하기 위한 State 패턴, 다양한 계정 유형을 위한 상속, 소유 관계를 위한 스마트 포인터, 트랜잭션 추적을 함께 사용합니다. 이는 이 과정에서 익힌 모든 핵심 개념입니다.
직접 해보기
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// 입력 1 읽기: 고객 정보 (형식: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// 입력 2 읽기: 저축 계좌 정보 (형식: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// 입력 3 읽기: 작업 1 (형식: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// 입력 4 읽기: 작업 2 (형식: action,accountNumber,amount 또는 freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: customerInput에서 고객 정보 파싱
// 힌트: find(',')를 사용하여 문자열 분할
// TODO: accountInput에서 계좌 정보 파싱
// TODO: 은행 생성
// TODO: 고객 생성
// TODO: 고객을 소유자로 하는 저축 계좌 생성
// TODO: 고객에 계좌 추가
// TODO: 은행에 고객 추가
// TODO: 연산 1 파싱 및 처리
// 형식: action,accountNumber,amount (action은 "deposit" 또는 "withdraw")
// TODO: 연산 2 파싱 및 처리
// 다음일 수 있음: action,accountNumber,amount 또는 freeze,accountNumber
// freeze인 경우, 계좌를 동결한 다음 $10 출금을 시도
// TODO: 고객의 계좌 목록 출력
// TODO: Print transaction count as "Transactions: [count]"
return 0;
}
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러