نظام مصرفي
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 63 من 65.
التحدي
صعبأنشئ بنكًا يضم نوعين من الحسابات. تُعيد كل عملية قاموس نتيجة {"ok": bool, "message": String}؛ ويطبع الكود المرفق النتيجة بصيغة OK: MESSAGE أو Failed: MESSAGE. جميع المبالغ من النوع float، ويظهر كل مبلغ في الرسالة بمنزلتين عشريتين بعد $.
Transaction في transaction.gd: يأخذ المُنشئ kind ("deposit" أو "withdrawal" أو "interest") وamount. تُعيد _to_string() النوع بحرفه الأول كبيرًا، ثم المبلغ: Deposit - $200.00. لا يخزّن سجل المعاملة الحساب المرتبط به.
Account في account.gd فئة @abstract:
- يأخذ المُنشئ
account_numberوowner_nameوinitial_balance. تُخزّن الأموال في_balanceالخاص؛ أماbalanceفهي خاصية للقراءة فقط، ويُعيد مُسترجعها قيمة_balance. و_historyهيArray[Transaction]، وتُعيدget_history()هذه المصفوفة. - توجد طريقتان مجردتان:
account_type() -> Stringوwithdrawal_error(amount: float) -> String، التي تُعيد سبب رفض السحب، أو"". deposit(amount): إذا كان المبلغ0أو أقل، تفشل العملية معDeposit amount must be positive. وإلا تُضاف الأموال، ويُسجّل سجل معاملة من نوعdeposit، وتُعاد الرسالةDeposited $A. New balance: $B.withdraw(amount): إذا كان المبلغ0أو أقل، تفشل العملية معWithdrawal amount must be positive؛ وإذا أعادتwithdrawal_error()نصًا غير فارغ، تفشل العملية مع ذلك النص. وإلا تُسحب الأموال، ويُسجّل سجل معاملة من نوعwithdrawal، وتُعاد الرسالةWithdrew $A. New balance: $B، ويتبعها(Overdraft)عندما يصبح الرصيد أقل من0.- تُعيد
_to_string()القيمةTYPE NUMBER (OWNER): $BALANCE.
SavingsAccount في savings_account.gd ترث من Account، مع الثابتين INTEREST_RATE = 0.02 وMIN_BALANCE = 100.0. نوعها هو Savings. يُرفض السحب الذي سيجعل الرصيد أقل من MIN_BALANCE مع الرسالة Cannot withdraw below minimum balance of $100.00. تضيف apply_interest() قيمة balance * INTEREST_RATE، وتسجّل سجل معاملة من نوع interest، وتُعيد الرسالة Applied interest: $I. New balance: $B.
CheckingAccount في checking_account.gd ترث من Account، مع الثابت OVERDRAFT_LIMIT = 200.0. نوعها هو Checking. يمكن أن ينخفض الرصيد حتى -200.00؛ ويُرفض السحب الذي سيخفضه أكثر من ذلك مع الرسالة Cannot exceed overdraft limit of $200.00.
يحتفظ Bank في bank.gd بالحسابات في قاموس خاص، ويكون رقم الحساب هو المفتاح:
- يأخذ المُنشئ
bank_name. create_account(kind, account_number, owner_name, initial_balance)هي دالة مصنع: تكون قيمةkindإماsavingsأوchecking، بأي حالة للأحرف. وتفشل معAccount number already existsأوInvalid account type، وإلا فتُعيدSavings account created successfully(أوChecking).- تُعيد
get_account(account_number) -> Accountالحساب، أوnull. transfer(from_number, to_number, amount): تفشل معOne or both accounts not found؛ وتسحب من الحساب الأول، وإذا فشل السحب، تفشل معTransfer failed:متبوعًا برسالة السحب. وإلا فتودع المبلغ في الحساب الثاني وتُعيدTransferred $A from FROM to TO.- تُعيد
total_holdings() -> floatمجموع جميع الأرصدة.
يقرأ الكود المرفق اسم البنك، ثم الأوامر. بالنسبة إلى هذا الإدخال:
First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
totalيكون الناتج:
OK: Savings account created successfully
OK: Checking account created successfully
Failed: Cannot withdraw below minimum balance of $100.00
OK: Transferred $300.00 from S1 to C1
OK: Withdrew $400.00. New balance: $-50.00 (Overdraft)
History of C1:
1. Deposit - $300.00
2. Withdrawal - $400.00
Total held by First Bank: $650.00ضع الكود في transaction.gd وaccount.gd وsavings_account.gd وchecking_account.gd وbank.gd. يحتوي main.gd على كود الإدخال/الإخراج المرفق، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# شيفرة الإدخال/الإخراج المقدَّمة: اتركها كما هي
var bank := Bank.new(OS.read_string_from_stdin())
var line := OS.read_string_from_stdin()
while line != "":
var parts := line.split(" ", true, 1)
var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
match parts[0]:
"open":
show_result(bank.create_account(f[0], f[1], f[2], float(f[3])))
"deposit":
show_result(bank.get_account(f[0]).deposit(float(f[1])))
"withdraw":
show_result(bank.get_account(f[0]).withdraw(float(f[1])))
"interest":
var account: Account = bank.get_account(f[0])
if account is SavingsAccount:
var savings := account as SavingsAccount
show_result(savings.apply_interest())
else:
print("Failed: ", f[0], " is not a savings account")
"transfer":
show_result(bank.transfer(f[0], f[1], float(f[2])))
"history":
var history: Array = bank.get_account(f[0]).get_history()
print("History of ", f[0], ":")
for i in history.size():
print(i + 1, ". ", history[i])
"account":
print(bank.get_account(f[0]))
"total":
print("Total held by %s: $%.2f" % [bank.bank_name, bank.total_holdings()])
line = OS.read_string_from_stdin()
func show_result(result: Dictionary) -> void:
print(("OK: " if result["ok"] else "Failed: ") + result["message"])
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت