Menu
Coddy logo textTech

מימוש הסתרת נתונים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C# של Coddy. שיעור 33 מתוך 70.

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

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

public class UserAccount
{
    private string passwordHash;
    
    public void SetPassword(string password)
    {
        passwordHash = HashPassword(password);
    }
    
    public bool VerifyPassword(string password)
    {
        return HashPassword(password) == passwordHash;
    }
    
    private string HashPassword(string password)
    {
        return password.GetHashCode().ToString();
    }
}

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

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

challenge icon

אתגר

קל

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

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

  • Wallet.cs: צרו מחלקה בשם Wallet במרחב השמות Finance, שמסתירה לחלוטין את היתרה שלה. בארנק צריכים להיות:
    • שדה פרטי לאחסון היתרה (decimal)
    • מתודה פרטית FormatBalance() שמחזירה את היתרה כשהיא מעוצבת כמחרוזת מטבע, כמו "$123.45" — זהו כלי עזר פנימי שאסור לחשוף
    • מתודה ציבורית Deposit(decimal amount) שמוסיפה ליתרה רק אם הסכום חיובי, ומחזירה true אם הפעולה הצליחה, ו-false אחרת
    • מתודה ציבורית Withdraw(decimal amount) שמפחיתה מהיתרה רק אם הסכום חיובי ואינו עולה על היתרה הנוכחית, ומחזירה true אם הפעולה הצליחה, ו-false אחרת
    • מתודה ציבורית CanAfford(decimal amount) שמחזירה true אם היתרה גדולה מהסכום או שווה לו, ו-false אחרת
    • מתודה ציבורית GetStatement() שמשתמשת במתודה הפרטית FormatBalance() באופן פנימי ומחזירה "Current balance: {formatted balance}"
    שימו לב שאין דרך לקרוא את היתרה ישירות או לקבוע אותה — אפשר רק לפעול מולה באמצעות מתודות מבוקרות!
  • Program.cs: בקובץ הראשי שלכם, צרו Wallet ובצעו סדרת עסקאות באמצעות ערכי קלט. הראו כיצד הארנק מגן על המצב הפנימי שלו, ובו בזמן מספק שימושיות באמצעות הממשק הציבורי שלו.

תקבלו שלושה קלטים:

  • סכום ההפקדה הראשונית (decimal)
  • סכום המשיכה שיש לנסות (decimal)
  • הסכום שעבורו יש לבדוק אם ניתן לעמוד בתשלום (decimal)

הדפיסו את הפלט בפורמט הבא:

Deposit {amount}: {True/False}
{GetStatement() result}
Withdraw {amount}: {True/False}
{GetStatement() result}
Can afford {amount}: {True/False}

לדוגמה, אם הקלטים הם 100.50, 30.25 ו-80.00, הפלט צריך להיות:

Deposit 100.50: True
Current balance: $100.50
Withdraw 30.25: True
Current balance: $70.25
Can afford 80.00: False

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

נסו בעצמכם

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // קרא את ערכי הקלט
        decimal depositAmount = Convert.ToDecimal(Console.ReadLine());
        decimal withdrawAmount = Convert.ToDecimal(Console.ReadLine());
        decimal checkAmount = Convert.ToDecimal(Console.ReadLine());

        // TODO: צור מופע של Wallet
        
        // TODO: בצע הפקדה והדפס את התוצאה בפורמט: "Deposit {amount}: {True/False}"
        
        // TODO: הדפס את דף החשבון באמצעות GetStatement()
        
        // TODO: בצע משיכה והדפס את התוצאה בפורמט: "Withdraw {amount}: {True/False}"
        
        // TODO: הדפס את דף החשבון באמצעות GetStatement()
        
        // TODO: בדוק אם יש מספיק כסף והדפס את התוצאה בפורמט: "Can afford {amount}: {True/False}"
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

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

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