Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

النظام المصرفي

جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 89 من 91.

challenge icon

التحدي

سهل

لنبنِ نظامًا مصرفيًا يتعامل مع الحسابات والمعاملات والتحويلات بين الحسابات. ستنشئ نظامًا يتضمن التغليف المناسب لحماية البيانات المالية، والوراثة لأنواع الحسابات المختلفة، والتحقق لضمان سلامة البيانات.

ستنظم شيفرتك عبر ستة ملفات:

  • Transaction.php: أنشئ فئة Transaction لتسجيل العمليات المالية. استخدم ترقية المُنشئ للخصائص type (من النوع string: "deposit" أو "withdrawal" أو "transfer")، وamount (من النوع float)، وtimestamp (من النوع string). يجب أن تكون جميع الخصائص public readonly. أضف أسلوبًا getDescription(): string يعيد "[type]: $[amount]" (مع تنسيق المبلغ إلى منزلتين عشريتين).
  • BankAccount.php: ضمّن ملف Transaction. أنشئ فئة مجردة BankAccount تتضمن:
    • ترقية المُنشئ للخاصيتين accountNumber (من النوع string وpublic readonly) وholderName (من النوع string وpublic readonly)
    • خاصية $balance محمية، ومهيّأة بالقيمة 0.0
    • مصفوفة خاصة لتخزين سجل المعاملات
    • getBalance(): float: تعيد الرصيد الحالي
    • deposit(float $amount): string: تضيف إلى الرصيد، وتسجل المعاملة، وتعيد "Deposited: $[amount]"
    • abstract withdraw(float $amount): string: تطبق الفئات الابنة قواعد السحب
    • addTransaction(Transaction $t): void: أسلوب محمي لإضافة المعاملات إلى السجل
    • getTransactionCount(): int: يعيد عدد المعاملات
  • SavingsAccount.php: ضمّن ملف BankAccount. أنشئ فئة SavingsAccount تمتد من BankAccount وتتضمن:
    • ثابت فئة INTEREST_RATE مضبوطًا على 0.02 (أي 2%)
    • withdraw(float $amount): string: إذا تجاوز المبلغ الرصيد، فأعد "Insufficient funds"؛ وإلا فاطرح المبلغ، وسجّل المعاملة، وأعد "Withdrew: $[amount]"
    • applyInterest(): string: تحسب الفائدة على الرصيد الحالي، وتضيفها كإيداع، وتعيد "Interest applied: $[interest]"
  • CheckingAccount.php: ضمّن ملف BankAccount. أنشئ فئة CheckingAccount تمتد من BankAccount وتتضمن:
    • خاصية خاصة $overdraftLimit يتم ضبطها عبر المُنشئ (أضف معاملًا ثالثًا بقيمة افتراضية 100.0)
    • withdraw(float $amount): string: تسمح بالسحب إذا كان المبلغ لا يتجاوز الرصيد + حد السحب على المكشوف؛ وأعد "Insufficient funds (overdraft limit: $[limit])" عند الفشل، أو "Withdrew: $[amount]" عند النجاح
    • getOverdraftLimit(): float: يعيد حد السحب على المكشوف
  • Bank.php: ضمّن ملفي الحسابين. أنشئ فئة Bank تدير الحسابات:
    • مصفوفة خاصة لتخزين الحسابات المفهرسة حسب رقم الحساب
    • 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]" (بمنزلتين عشريتين)

    اطبع كل نتيجة في سطر جديد. نسّق جميع المبالغ المالية إلى منزلتين عشريتين.

تذكّر أن التحويلات يجب أن تكون ذرّية؛ فإذا فشل السحب، فلا ينبغي أن يحدث الإيداع. تسمح الخاصية المحمية $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:
//   - إذا كان النوع "savings"، أنشئ SavingsAccount
//   - إذا كان النوع "checking"، أنشئ CheckingAccount (مع السحب على المكشوف إذا تم توفيره)
//   - أضف الحساب إلى البنك
//   - أودع المبلغ الأولي

// TODO: عالج كل عملية
// لكل عملية في $operations:
//   - "deposit": اطبع نتيجة deposit()
//   - "withdraw": اطبع نتيجة withdraw()
//   - "transfer": اطبع نتيجة transfer()
//   - "interest": اطبع نتيجة applyInterest() (فقط لحسابات التوفير)
//   - "balance": اطبع "[holder] balance: $[balance]" (منزلتان عشريتان)

?>

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم PHP عبر الإنترنت