מימוש הסתרת נתונים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 היא פרטית, כי היא פרט מימוש שיכול להשתנות בלי להשפיע על אופן השימוש במחלקה.
הגישה הזאת מגינה על המחלקה שלך מפני שימוש לרעה ומאפשרת לך לשנות את המימוש הפנימי בהמשך. אם תחליט להשתמש באלגוריתם גיבוב אחר, שום קוד חיצוני לא יישבר, כי שום דבר לא היה תלוי באופן שבו הסיסמה נשמרה.
אתגר
קלבואו נבנה מערכת ארנק מאובטחת שמדגימה הסתרת נתונים אמיתית. תיצרו ארנק דיגיטלי שהיתרה בו מוגנת לחלוטין מפני גישה ישירה — קוד חיצוני יכול רק להפקיד, למשוך ולבדוק אם עסקאות אפשריות, אך לעולם לא לראות את היתרה עצמה או לשנות אותה ישירות.
תארגנו את הקוד שלכם בשני קבצים:
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}"
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמרחבי שמות והנחיותמבוא למחלקות ולאובייקטיםמילת המפתח 'this'מתודות ופרמטריםשדות לעומת מאפייניםבנאיםאתחול אובייקטיםסיכום – מחשבון פשוט4ירושה
תחביר ירושה בסיסית (:)מילת המפתח 'base'מילות המפתח Virtual ו-Overrideמחלקות Sealedמחלקת הבסיס 'object'סיכום – היררכיית עובדים7תכונות מתקדמות
העמסת אופרטוריםאינדקסרים (this[])דריסת ToString()מתודות הרחבהסיכום – רשימה מותאמת אישית2מאפיינים וחברים סטטיים
מאפיינים במימוש אוטומטימאפיינים לקריאה בלבד ולכתיבה בלבדשדות ומתודות סטטייםמחלקות סטטיותחברים עם גוף ביטוי5פולימורפיזם וממשקים
פולימורפיזם בזמן קומפילציה לעומת בזמן ריצהממשק לעומת מחלקה מופשטתממשקים מרוביםממשקים מפורשיםהמרה כלפי מעלה והמרה כלפי מטהחזרה: מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה במקום ירושהGenerics (מחלקות ומתודות)נציגים ואירועיםמאפיינים ורפלקציהIDisposable והצהרת usingיסודות הזרקת תלויותתרגלו בעצמכם: קומפיילר C# אונליין