Menu
Coddy logo textTech

은행 시스템

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

challenge icon

챌린지

쉬움

Banking System을 만들어 계정, 거래 및 계정 간 이체를 처리해 봅시다. 금융 데이터를 보호하기 위한 적절한 캡슐화, 다양한 계정 유형을 위한 상속, 데이터 무결성을 보장하기 위한 검증을 갖춘 시스템을 만들게 됩니다.

코드를 다음 6개의 파일로 구성합니다.

  • Transaction.php: 금융 작업을 기록하는 Transaction class를 Create합니다. type (문자열: "deposit", "withdrawal", 또는 "transfer"), amount (실수), timestamp (문자열)에 생성자 프로모션을 사용합니다. 모든 속성은 public readonly여야 합니다. "[type]: $[amount]"를 반환하는 getDescription(): string 메서드를 Add합니다 (amount를 소수점 이하 2자리로 형식화).
  • BankAccount.php: Transaction 파일을 포함합니다. 다음을 갖는 abstract BankAccount class를 Create합니다.
    • accountNumber (문자열, public readonly) 및 holderName (문자열, public readonly)에 생성자 프로모션을 사용
    • 0.0으로 초기화된 protected $balance 속성
    • 거래 내역을 저장할 private array
    • getBalance(): float: current balance를 반환
    • deposit(float $amount): string: balance에 Add하고, 거래를 기록하며, "Deposited: $[amount]"를 반환
    • abstract withdraw(float $amount): string: 자식 class가 인출 규칙을 구현
    • addTransaction(Transaction $t): void: 거래를 내역에 Add하는 protected 메서드
    • getTransactionCount(): int: 거래 수를 반환
  • SavingsAccount.php: BankAccount 파일을 포함합니다. 다음을 갖고 BankAccount를 확장하는 SavingsAccount class를 Create합니다.
    • 0.02 (2%)로 설정된 class constant INTEREST_RATE
    • withdraw(float $amount): string: amount가 balance를 exceed하면 "Insufficient funds"를 반환하고, 그렇지 않으면 deduct하고 거래를 기록한 뒤 "Withdrew: $[amount]"를 반환
    • applyInterest(): string: current balance에 대한 이자를 계산하고 이를 deposit으로 Add한 뒤 "Interest applied: $[interest]"를 반환
  • CheckingAccount.php: BankAccount 파일을 포함합니다. 다음을 갖고 BankAccount를 확장하는 CheckingAccount class를 Create합니다.
    • 생성자를 통해 설정되는 private $overdraftLimit 속성 (기본값 100.0인 세 번째 매개변수를 Add)
    • withdraw(float $amount): string: amount가 balance + overdraft limit를 exceed하지 않으면 인출을 허용합니다. 실패 시 "Insufficient funds (overdraft limit: $[limit])"를 반환하고, 성공 시 "Withdrew: $[amount]"를 반환
    • getOverdraftLimit(): float: overdraft limit를 반환
  • Bank.php: 두 account 파일을 모두 포함합니다. accounts를 관리하는 Bank class를 Create합니다.
    • account number를 인덱스로 accounts를 저장할 private array
    • addAccount(BankAccount $account): void: account를 Add
    • findAccount(string $accountNumber): ?BankAccount: account 또는 null을 반환
    • transfer(string $fromAccount, string $toAccount, float $amount): string: accounts 간에 money를 이체합니다. "Source account not found", "Destination account not found" 또는 실패한 경우 인출 결과를 반환합니다. 성공하면 destination에 deposit하고 "Transferred $[amount] from [from] to [to]"를 반환
  • main.php: Bank 파일을 포함합니다. 두 개의 입력, 즉 accounts data (JSON)와 operations (JSON)를 받습니다.

    Accounts JSON 형식:

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

    Operations 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"}]

    bank와 모든 accounts를 Create합니다 (initial amounts를 deposit). 각 operation을 처리합니다.

    • "deposit": deposit()의 결과를 Print
    • "withdraw": withdraw()의 결과를 Print
    • "transfer": transfer()의 결과를 Print
    • "interest": applyInterest()의 결과를 Print (savings accounts에만 적용)
    • "balance": "[holder] balance: $[balance]"를 Print (소수점 이하 2자리)

    각 결과를 새 줄에 Print합니다. 모든 monetary amounts를 소수점 이하 2자리로 형식화합니다.

이체는 atomic이어야 한다는 점을 기억하세요. 인출이 실패하면 deposit이 발생해서는 안 됩니다. protected $balance 속성을 사용하면 자식 class가 이를 수정하면서도 외부 코드에는 숨길 수 있으므로, 금융 환경에서 적절한 캡슐화를 보여 줍니다.

직접 해보기

<?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 데이터로부터 계좌 생성
// $accounts의 각 계좌에 대해:
//   - type이 "savings"이면 SavingsAccount 생성
//   - type이 "checking"이면 CheckingAccount 생성 (overdraft가 제공된 경우 포함)
//   - 계좌를 bank에 추가
//   - 초기 금액 입금

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

?>

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

직접 연습해 보세요: 온라인 PHP 컴파일러