Menu
Coddy logo textTech

銀行システム

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 89/91。

challenge icon

チャレンジ

簡単

Banking System を構築しましょう。アカウント、取引、アカウント間の送金を処理します。金融データを保護する適切なカプセル化、異なるアカウント種別に対応する継承、そしてデータの整合性を保証する検証を備えたシステムを作成します。

コードを6つのファイルに整理します。

  • Transaction.php:金融操作を記録する Transaction class を作成します。type(string: "deposit"、"withdrawal"、または "transfer")、amount(float)、timestamp(string)にはコンストラクタプロパティプロモーションを使用します。すべてのプロパティは public readonly にします。getDescription(): string メソッドを追加し、"[type]: $[amount]" を返すようにします(amount は小数点以下2桁にフォーマットします)。
  • BankAccount.php:Transaction ファイルを読み込みます。次の要素を持つ abstract BankAccount class を作成します。
    • accountNumber(string、public readonly)と holderName(string、public readonly)に対するコンストラクタプロパティプロモーション
    • 0.0 に初期化された protected $balance property
    • 取引履歴を保存する private array
    • getBalance(): float:current balance を返す
    • deposit(float $amount): string:balance に加算し、取引を記録して、"Deposited: $[amount]" を返す
    • abstract withdraw(float $amount): string:子 class で引き出しルールを実装する
    • addTransaction(Transaction $t): void:取引を履歴に追加する protected method
    • getTransactionCount(): int:取引数を返す
  • SavingsAccount.php:BankAccount ファイルを読み込みます。BankAccount を継承する SavingsAccount class を作成し、次の要素を追加します。
    • 0.02(2%)に設定された class constant INTEREST_RATE
    • withdraw(float $amount): string:amount が balance を exceed する場合は "Insufficient funds" を返します。それ以外の場合は deduct して取引を記録し、"Withdrew: $[amount]" を返します
    • applyInterest(): string:current balance に対する利息を計算し、deposit として加算して、"Interest applied: $[interest]" を返します
  • CheckingAccount.php:BankAccount ファイルを読み込みます。BankAccount を継承する CheckingAccount class を作成し、次の要素を追加します。
    • コンストラクタで設定する private $overdraftLimit property(デフォルト値 100.0 の3つ目のパラメータを追加します)
    • withdraw(float $amount): string:amount が balance + overdraft limit を exceed しない場合に引き出しを許可します。失敗時は "Insufficient funds (overdraft limit: $[limit])" を返し、成功時は "Withdrew: $[amount]" を返します
    • getOverdraftLimit(): float:overdraft limit を返します
  • Bank.php:両方のアカウントファイルを読み込みます。アカウントを管理する Bank class を作成します。
    • account number をインデックスとしてアカウントを保存する private array
    • addAccount(BankAccount $account): void:アカウントを追加します
    • findAccount(string $accountNumber): ?BankAccount:アカウント、または null を返します
    • transfer(string $fromAccount, string $toAccount, float $amount): string:アカウント間で money を transfer します。"Source account not found""Destination account not found"、または失敗した場合は withdrawal の結果を返します。成功時は destination に deposit し、"Transferred $[amount] from [from] to [to]" を返します
  • main.php:Bank ファイルを読み込みます。2つの入力、つまり 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 とすべてのアカウントを作成し、initial amounts を deposit します。各 operation を処理します。

    • "deposit"deposit() の結果を出力します
    • "withdraw"withdraw() の結果を出力します
    • "transfer"transfer() の結果を出力します
    • "interest"applyInterest() の結果を出力します(savings accounts の場合のみ)
    • "balance""[holder] balance: $[balance]" を出力します(小数点以下2桁)

    各結果を新しい行に出力します。すべての monetary amounts は小数点以下2桁にフォーマットします。

transfer は atomic である必要があることに注意してください。withdrawal が fails した場合、deposit は実行されてはいけません。protected $balance property により、子 class はその値を変更できますが、外部 code からは hidden のままになります。これは金融 context における適切なカプセル化を示しています。

自分で試してみよう

<?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を作成する(提供されていればoverdraft付き)
//   - 口座をbankに追加する
//   - 初期金額を入金する

// TODO: 各操作を処理する
// $operations内の各操作について:
//   - "deposit": deposit()の結果を出力する
//   - "withdraw": withdraw()の結果を出力する
//   - "transfer": transfer()の結果を出力する
//   - "interest": applyInterest()の結果を出力する(savingsのみ)
//   - "balance": "[holder] balance: $[balance]"を出力する(小数点以下2桁)

?>

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: PHPオンラインコンパイラ