النظام المصرفي
جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 89 من 91.
التحدي
سهللنبنِ نظامًا مصرفيًا يتعامل مع الحسابات والمعاملات والتحويلات بين الحسابات. ستنشئ نظامًا يتضمن التغليف المناسب لحماية البيانات المالية، والوراثة لأنواع الحسابات المختلفة، والتحقق لضمان سلامة البيانات.
ستنظم شيفرتك عبر ستة ملفات:
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: تعيد الحساب أو nulltransfer(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]" (منزلتان عشريتان)
?>جميع دروس البرمجة كائنية التوجه
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsالكلمة المفتاحية $thisالـ Methodsالـ Propertiesالمنشئ (__construct)الهادم (__destruct)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةالكلمة المفتاحية parent::إعادة تعريف الدوال (Method Overriding)الكلمة المفتاحية finalالأصناف المجردة (Abstract Classes)مراجعة - هيكلية الموظفين7التغليف (Encapsulation)
العام، المحمي، الخاص (Public, Protected, Private)نظرة متعمقة على معدلات الوصولدوال Getters و Settersإخفاء المعلوماتميزة Constructor Promotion (8.0)مراجعة - نظام سجلات الطلاب10مفاهيم البرمجة كائنية التوجه المتقدمة
التركيب مقابل الوراثةحقن التبعيةالأصناف المجهولةالتعدادات (PHP 8.1)الألياف (PHP 8.1)تعمق في استنساخ الكائناتالمولدات والمكررات13أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع2مساحات الأسماء والتحميل التلقائي
مقدمة إلى مساحات الأسماءالكلمة المفتاحية useمعيار التحميل التلقائي PSR-4أداة التحميل التلقائي Composerملخص - مشروع منظم5الواجهات والعقود
مقدمة إلى الواجهاتتنفيذ الواجهاتتنفيذ واجهات متعددةالواجهة مقابل الـ Abstract Classالـ Type Hinting مع الواجهاتملخص - حاسبة الأشكال8الميثودات السحرية (Magic Methods)
مقدمة في الميثودات السحرية__toString و __debugInfo__get, __set, __isset, __unset__call و __callStatic__clone واستنساخ الكائنات__serialize و __unserializeمراجعة - Custom Collection3خصائص الكلاس
خصائص الـ Instance مقابل الخصائص الساكنة (Static)الثوابت في الكلاساتالدوال والخصائص الساكنة (Static)الخصائص الخاصة (Private) والمحمية (Protected)خصائص للقراءة فقط (Readonly) في PHP 8.1مراجعة - مدير الحساب البنكي6تعدد الأشكال (Polymorphism)
مراجعة إعادة تعريف الدوال (Method Overriding)تعدد الأشكال عبر الـ Interfacesتلميح النوع (Type Hinting) وأنواع الاتحاد (Union Types)الربط الاستاتيكي المتأخر (Late Static Binding)ملخص - معالج الدفع (Payment Processor)تدرّب بنفسك: مترجم PHP عبر الإنترنت