Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

تنفيذ إخفاء البيانات

جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 33 من 70.

يتجاوز إخفاء البيانات مجرد استخدام حقول private. يتعلق الأمر بتصميم فئتك بحيث تكون تفاصيل التنفيذ الداخلية غير مرئية تمامًا للكود الخارجي، مع الكشف فقط عما هو ضروري من خلال واجهة عامة نظيفة.

فكر في فئة (class) تتتبع كلمة مرور المستخدم. أنت لا تريد أن يتمكن أي شخص من الوصول إلى كلمة المرور الخام - ولا حتى لقراءتها:

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();
    }
}

لاحظ أنه لا توجد طريقة لاسترداد كلمة المرور أو حتى الهاش (hash). يمكن للكود الخارجي فقط تعيين كلمة مرور أو التحقق منها - فآلية التخزين الداخلية مخفية تماماً. كما أن طريقة HashPassword هي أيضاً خاصة (private) لأنها من تفاصيل التنفيذ التي قد تتغير دون التأثير على كيفية استخدام الفئة (class).

يحمي هذا النهج الـ class الخاص بك من سوء الاستخدام ويمنحك الحرية لتغيير الأجزاء الداخلية لاحقاً. إذا قررت استخدام hashing algorithm مختلفة، فلن يتوقف أي كود خارجي عن العمل لأن لا شيء يعتمد على كيفية تخزين كلمة المرور.

challenge icon

التحدي

سهل

لنقم ببناء نظام محفظة آمن يوضح المفهوم الحقيقي لإخفاء البيانات (data hiding). ستقوم بإنشاء محفظة رقمية حيث يكون الرصيد محميًا تمامًا من الوصول المباشر - يمكن للكود الخارجي فقط الإيداع، السحب، والتحقق مما إذا كانت المعاملات ممكنة، ولكن لا يمكنه أبدًا رؤية أو التلاعب بالرصيد الفعلي مباشرة.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • Wallet.cs: أنشئ فئة Wallet داخل مساحة الأسماء Finance التي تحافظ على رصيدها مخفيًا تمامًا. يجب أن تحتوي المحفظة على:
    • حقل خاص (private field) لتخزين الرصيد (decimal)
    • طريقة خاصة (private method) باسم FormatBalance() تعيد الرصيد منسقًا كسلسلة نصية للعملة مثل "$123.45" - هذه أداة مساعدة داخلية لا ينبغي كشفها للخارج
    • طريقة عامة (public method) باسم Deposit(decimal amount) تضيف إلى الرصيد فقط إذا كان المبلغ موجبًا، وتعيد true إذا نجحت العملية، و false خلاف ذلك
    • طريقة عامة (public method) باسم Withdraw(decimal amount) تطرح من الرصيد فقط إذا كان المبلغ موجبًا ولا يتجاوز الرصيد الحالي، وتعيد true إذا نجحت العملية، و false خلاف ذلك
    • طريقة عامة (public method) باسم CanAfford(decimal amount) تعيد true إذا كان الرصيد أكبر من أو يساوي المبلغ، و false خلاف ذلك
    • طريقة عامة (public method) باسم 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

الفكرة الجوهرية هنا هي أن الكود الخارجي لا يلمس حقل الرصيد مباشرة أبدًا. حتى سلسلة الرصيد المنسقة تأتي من خلال طريقة عامة تستخدم داخليًا أداة مساعدة خاصة. هذا هو إخفاء البيانات - تفاصيل التنفيذ غير مرئية تمامًا، وأنت حر في تغيير كيفية تخزين الرصيد أو تنسيقه دون كسر أي كود يستخدم محفظتك!

ورقة مرجعية

إخفاء البيانات يعني تصميم الفئات بحيث تكون تفاصيل التنفيذ الداخلية غير مرئية تمامًا للكود الخارجي، مع كشف ما هو ضروري فقط من خلال واجهة عامة نظيفة.

استخدم الحقول private لتخزين البيانات الحساسة وتوفير وصول محكوم من خلال الأساليب public:

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();
    }
}

المبادئ الأساسية:

  • لا يوجد وصول مباشر للبيانات الداخلية (لا توجد دوال جلب للحقول الحساسة)
  • أساليب مساعدة خاصة (Private) لتفاصيل التنفيذ
  • توفر الأساليب العامة (Public) عمليات محكومة فقط
  • آلية التخزين الداخلية مخفية تمامًا

يحمي هذا الفئة من سوء الاستخدام ويسمح بتغيير التنفيذ الداخلي دون كسر الكود الخارجي.

جرّب بنفسك

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اختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming