Menu
Coddy logo textTech

מערכת בנקאית

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 89 מתוך 91.

challenge icon

אתגר

קל

בואו נבנה מערכת בנקאית שמטפלת בחשבונות, בעסקאות ובהעברות בין חשבונות. תיצרו מערכת עם כימוס מתאים כדי להגן על נתונים פיננסיים, ירושה עבור סוגי חשבונות שונים ואימות כדי להבטיח את שלמות הנתונים.

תארגנו את הקוד שלכם בשישה קבצים:

  • Transaction.php: צרו מחלקה בשם Transaction לתיעוד פעולות פיננסיות. השתמשו בקידום מאפיינים בבנאי עבור type (מחרוזת: "deposit", "withdrawal", או "transfer"), amount (מספר ממשי) ו-timestamp (מחרוזת). כל המאפיינים צריכים להיות public readonly. הוסיפו מתודה getDescription(): string שמחזירה "[type]: $[amount]" (עצבו את הסכום עם 2 ספרות אחרי הנקודה העשרונית).
  • BankAccount.php: כללו את קובץ Transaction. צרו מחלקה מופשטת בשם BankAccount עם:
    • קידום מאפיינים בבנאי עבור accountNumber (מחרוזת, public readonly) ועבור holderName (מחרוזת, 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]" (2 ספרות אחרי הנקודה העשרונית)

    הדפיסו כל תוצאה בשורה חדשה. עצבו את כל הסכומים הכספיים עם 2 ספרות אחרי הנקודה העשרונית.

זכרו שהעברות צריכות להיות אטומיות: אם המשיכה נכשלת, ההפקדה לא צריכה להתבצע. המאפיין המוגן $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]" (עם 2 ספרות אחרי הנקודה העשרונית)

?>

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר PHP אונליין