銀行システム
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 89/91。
チャレンジ
簡単Banking System を構築しましょう。アカウント、取引、アカウント間の送金を処理します。金融データを保護する適切なカプセル化、異なるアカウント種別に対応する継承、そしてデータの整合性を保証する検証を備えたシステムを作成します。
コードを6つのファイルに整理します。
Transaction.php:金融操作を記録するTransactionclass を作成します。type(string: "deposit"、"withdrawal"、または "transfer")、amount(float)、timestamp(string)にはコンストラクタプロパティプロモーションを使用します。すべてのプロパティは public readonly にします。getDescription(): stringメソッドを追加し、"[type]: $[amount]"を返すようにします(amount は小数点以下2桁にフォーマットします)。BankAccount.php:Transaction ファイルを読み込みます。次の要素を持つ abstractBankAccountclass を作成します。accountNumber(string、public readonly)とholderName(string、public readonly)に対するコンストラクタプロパティプロモーション- 0.0 に初期化された protected
$balanceproperty - 取引履歴を保存する private array
getBalance(): float:current balance を返すdeposit(float $amount): string:balance に加算し、取引を記録して、"Deposited: $[amount]"を返すabstract withdraw(float $amount): string:子 class で引き出しルールを実装するaddTransaction(Transaction $t): void:取引を履歴に追加する protected methodgetTransactionCount(): int:取引数を返す
SavingsAccount.php:BankAccount ファイルを読み込みます。BankAccountを継承するSavingsAccountclass を作成し、次の要素を追加します。- 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]"を返します
- 0.02(2%)に設定された class constant
CheckingAccount.php:BankAccount ファイルを読み込みます。BankAccountを継承するCheckingAccountclass を作成し、次の要素を追加します。- コンストラクタで設定する private
$overdraftLimitproperty(デフォルト値 100.0 の3つ目のパラメータを追加します) withdraw(float $amount): string:amount が balance + overdraft limit を exceed しない場合に引き出しを許可します。失敗時は"Insufficient funds (overdraft limit: $[limit])"を返し、成功時は"Withdrew: $[amount]"を返しますgetOverdraftLimit(): float:overdraft limit を返します
- コンストラクタで設定する private
Bank.php:両方のアカウントファイルを読み込みます。アカウントを管理するBankclass を作成します。- 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オンラインコンパイラ