Menu
Coddy logo textTech

뱅킹 시스템

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 89번째.

challenge icon

챌린지

쉬움

계좌, 거래 및 계좌 간 이체를 처리하는 은행 시스템(Banking System)을 구축해 보겠습니다. 금융 데이터를 보호하기 위한 적절한 캡슐화, 다양한 계좌 유형을 위한 상속, 데이터 무결성을 보장하기 위한 유효성 검사를 갖춘 시스템을 만들게 됩니다.

코드는 다음 6개의 파일로 구성됩니다.

  • Transaction.php — 금융 거래를 기록하기 위한 Transaction 클래스를 생성합니다. type (string — "deposit", "withdrawal", 또는 "transfer"), amount (float), timestamp (string)에 대해 생성자 프로모션(constructor promotion)을 사용하세요. 모든 속성은 public readonly여야 합니다. "[type]: $[amount]"를 반환하는 getDescription(): string 메서드를 추가하세요 (금액은 소수점 둘째 자리까지 형식화).
  • BankAccount.php — Transaction 파일을 포함합니다. 다음을 포함하는 추상 BankAccount 클래스를 생성합니다.
    • accountNumber (string, public readonly) 및 holderName (string, public readonly)에 대한 생성자 프로모션
    • 0.0으로 초기화된 protected $balance 속성
    • 거래 내역을 저장하기 위한 private 배열
    • getBalance(): float — 현재 잔액을 반환
    • deposit(float $amount): string — 잔액에 추가하고, 거래를 기록하며, "Deposited: $[amount]"를 반환
    • abstract withdraw(float $amount): string — 자식 클래스에서 출금 규칙을 구현
    • addTransaction(Transaction $t): void — 거래 내역에 거래를 추가하는 protected 메서드
    • getTransactionCount(): int — 거래 횟수를 반환
  • SavingsAccount.php — BankAccount 파일을 포함합니다. BankAccount를 상속받는 SavingsAccount 클래스를 생성합니다.
    • 0.02 (2%)로 설정된 클래스 상수 INTEREST_RATE
    • withdraw(float $amount): string — 금액이 잔액을 초과하면 "Insufficient funds"를 반환하고, 그렇지 않으면 차감하고 거래를 기록한 뒤 "Withdrew: $[amount]"를 반환
    • applyInterest(): string — 현재 잔액에 대한 이자를 계산하여 입금으로 추가하고, "Interest applied: $[interest]"를 반환
  • CheckingAccount.php — BankAccount 파일을 포함합니다. BankAccount를 상속받는 CheckingAccount 클래스를 생성합니다.
    • 생성자를 통해 설정되는 private $overdraftLimit 속성 (기본값 100.0인 세 번째 매개변수 추가)
    • withdraw(float $amount): string — 금액이 잔액 + 마이너스 한도(overdraft limit)를 초과하지 않는 경우 출금을 허용합니다. 실패 시 "Insufficient funds (overdraft limit: $[limit])"를 반환하고, 성공 시 "Withdrew: $[amount]"를 반환
    • getOverdraftLimit(): float — 마이너스 한도를 반환
  • Bank.php — 두 계좌 파일을 모두 포함합니다. 계좌를 관리하는 Bank 클래스를 생성합니다.
    • 계좌 번호를 키로 하여 계좌를 저장하는 private 배열
    • addAccount(BankAccount $account): void — 계좌를 추가
    • findAccount(string $accountNumber): ?BankAccount — 계좌를 반환하거나 null을 반환
    • transfer(string $fromAccount, string $toAccount, float $amount): string — 계좌 간에 돈을 이체합니다. "Source account not found", "Destination account not found" 또는 출금 실패 시 그 결과를 반환합니다. 성공하면 대상 계좌에 입금하고 "Transferred $[amount] from [from] to [to]"를 반환
  • main.php — Bank 파일을 포함합니다. 계좌 데이터(JSON)와 작업(JSON)이라는 두 가지 입력을 받습니다.

    계좌 JSON 형식:

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

    작업 JSON 형식:

    [{"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"}]

    은행과 모든 계좌를 생성합니다(초기 금액 입금). 각 작업을 처리합니다.

    • "deposit"deposit()의 결과를 출력
    • "withdraw"withdraw()의 결과를 출력
    • "transfer"transfer()의 결과를 출력
    • "interest"applyInterest()의 결과를 출력 (저축 계좌인 경우에만)
    • "balance""[holder] balance: $[balance]"를 출력 (소수점 둘째 자리까지)

    각 결과를 새 줄에 출력하세요. 모든 통화 금액은 소수점 둘째 자리까지 형식화하세요.

이체는 원자적(atomic)이어야 함을 기억하세요. 즉, 출금이 실패하면 입금이 일어나서는 안 됩니다. protected $balance 속성은 외부 코드로부터는 숨기면서 자식 클래스가 이를 수정할 수 있도록 허용하여, 금융 문맥에서의 적절한 캡슐화를 보여줍니다.

직접 해보기

<?php

require_once 'Bank.php';

// 입력 읽기
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));

// JSON 입력 파싱
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);

// TODO: Bank 인스턴스 생성

// TODO: 계좌 데이터를 사용하여 계좌 생성
// $accounts의 각 계좌에 대해:
//   - type이 "savings"인 경우, SavingsAccount 생성
//   - type이 "checking"인 경우, CheckingAccount 생성 (마이너스 한도가 제공된 경우 포함)
//   - 은행에 계좌 추가
//   - 초기 금액 입금

// TODO: 각 작업 처리
// $operations의 각 작업에 대해:
//   - "deposit": deposit() 결과 출력
//   - "withdraw": withdraw() 결과 출력
//   - "transfer": transfer() 결과 출력
//   - "interest": applyInterest() 결과 출력 (저축 계좌만 해당)
//   - "balance": "[holder] balance: $[balance]" 출력 (소수점 2자리까지)

?>

객체 지향 프로그래밍의 모든 레슨