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

إخفاء المعلومات

جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 30 من 64.

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

إليك مثال على فئة (class) بمستويات مختلفة من إخفاء المعلومات:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # عام - يمكن الوصول إليه مباشرة
        self._balance = initial_balance       # محمي - للاستخدام الداخلي
        self.__account_number = "ACC123456"   # خاص - مخفي عن الخارج

أضف دوال (methods) توفر وصولاً متحكماً فيه للبيانات المخفية:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner
        self._balance = initial_balance
        self.__account_number = "ACC123456"
        
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
            return True
        return False
    
    def withdraw(self, amount):
        if amount > 0 and amount <= self._balance:
            self._balance -= amount
            return True
        return False
    
    def get_balance(self):
        return self._balance
    
    def get_account_info(self):
        # طريقة آمنة لعرض بيانات خاصة جزئية
        return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"

استخدم الفئة من خلال واجهتها العامة:

account = BankAccount("Alice", 1000)

الوصول إلى البيانات العامة مباشرة:

print(account.owner)  # Alice - الوصول العام مسموح

استخدم طرقاً محكومة للبيانات المحمية:

print(account.get_balance())  # 1000 - وصول محكوم
account.deposit(500)
print(account.get_balance())  # 1500 - تم تغيير الرصيد بأمان

حاول الوصول إلى البيانات المخفية:

print(account.get_account_info())  # المالك: Alice، الحساب: ***3456
# print(account.__account_number)  # AttributeError - مخفي

السمة الخاصة (private attribute) تخضع لعملية تشويه الاسم (name-mangling) ولكن لا يزال من الممكن الوصول إليها تقنيًا:

# هذا يعمل ولكنه ينتهك مبدأ إخفاء المعلومات:
print(account._BankAccount__account_number)  # ACC123456

المخرجات:

Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456

نقطة رئيسية: يحمي إخفاء المعلومات البيانات الداخلية من خلال جعلها خاصة (private) أو محمية (protected)، ثم توفير وصول متحكم فيه من خلال طرق عامة (public methods). يمنع هذا التلاعب المباشر بالبيانات الحساسة ويضمن سلامة البيانات من خلال التحقق من الصحة في طرق الوصول.

challenge icon

التحدي

متوسط

في هذا التحدي، ستقوم بتنفيذ نظام مراسلة آمن مع اختبار شامل للتحقق من صحة الحل الخاص بك.

تحتاج إلى تعديل securemessenger.py لتنفيذ فئة SecureMessenger باتباع مبادئ إخفاء المعلومات. يحتوي الملف على تعليقات TODO مفصلة لتوجيه عملية التنفيذ الخاصة بك.

تشمل المتطلبات الأساسية ما يلي:

  • التغليف السليم لبيانات الاعتماد والرسائل
  • المصادقة قبل السماح بعمليات الرسائل
  • مراقبة الأمان من خلال تتبع محاولات تسجيل الدخول
  • رسائل إرجاع دقيقة كما هو محدد في تعليقات TODO

ورقة مرجعية

يؤدي إخفاء المعلومات إلى تقييد الوصول المباشر إلى مكونات الكائن من خلال معدلات الوصول:

  • public - يمكن الوصول إليه مباشرة (بدون شرطة سفلية)
  • _protected - للاستخدام الداخلي (شرطة سفلية واحدة)
  • __private - مخفي عن الخارج (شرطة سفلية مزدوجة)
class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # عام (Public)
        self._balance = initial_balance       # محمي (Protected)
        self.__account_number = "ACC123456"   # خاص (Private)

توفير وصول محكوم من خلال الأساليب العامة:

def get_balance(self):
    return self._balance

def deposit(self, amount):
    if amount > 0:
        self._balance += amount
        return True
    return False

يتم تشويه أسماء السمات الخاصة (name-mangled) ولكن لا يزال من الممكن الوصول إليها:

# ينتهك إخفاء المعلومات ولكنه يعمل:
print(account._BankAccount__account_number)

جرّب بنفسك

from securemessenger import SecureMessenger

# معالج حالات الاختبار
test_case = input()
if test_case == "default_test":
    # حالة اختبار قياسية من المشكلة الأصلية
    messenger = SecureMessenger("user1")
    
    # محاولة إضافة رسائل قبل تسجيل الدخول
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # محاولة تسجيل الدخول بكلمة مرور خاطئة
    print(messenger.login("wrong_pass"))
    
    # تسجيل الدخول بكلمة مرور صحيحة
    print(messenger.login("secure123"))
    
    # إضافة رسائل بعد تسجيل الدخول الناجح
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # استرجاع الرسائل
    print(messenger.get_messages())
    
    # التحقق من محاولات تسجيل الدخول
    print(messenger.get_login_attempts())
elif test_case == "custom_password":
    # اختبار بكلمة مرور مخصصة
    messenger = SecureMessenger("admin", "admin123")
    print(messenger.login("wrong_password"))
    print(messenger.login("admin123"))
    print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
    # اختبار محاولات تسجيل دخول متعددة
    messenger = SecureMessenger("user2")
    print(messenger.login("attempt1"))
    print(messenger.login("attempt2"))
    print(messenger.login("attempt3"))
    print(messenger.login("secure123"))
    print(messenger.get_login_attempts())
elif test_case == "message_management":
    # اختبار إدارة الرسائل
    messenger = SecureMessenger("user3")
    print(messenger.login("secure123"))
    
    # إضافة رسائل متعددة
    messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
    for msg in messages:
        print(messenger.add_message(msg))
    
    # التحقق من جميع الرسائل
    print(messenger.get_messages())
elif test_case == "empty_messages":
    # اختبار حالة الرسائل الفارغة
    messenger = SecureMessenger("user4")
    print(messenger.login("secure123"))
    print(messenger.get_messages())
elif test_case == "access_without_login":
    # اختبار الوصول بدون تسجيل دخول
    messenger = SecureMessenger("user5")
    print(messenger.add_message("Unauthorized message"))
    print(messenger.get_messages())
elif test_case == "attribute_privacy":
    # اختبار خصوصية الخصائص
    messenger = SecureMessenger("user6")
    
    # خاصية عامة
    print(f"Public username: {messenger.username}")
    
    # خصائص خاصة - يجب أن تثير هذه الخصائص AttributeError
    try:
        print(messenger.__password)
    except AttributeError as e:
        print("Password is private: AttributeError")
    
    try:
        print(messenger.__messages)
    except AttributeError as e:
        print("Messages are private: AttributeError")
    
    try:
        print(messenger.__login_attempts)
    except AttributeError as e:
        print("Login attempts are private: AttributeError")
    
    try:
        print(messenger.__is_logged_in)
    except AttributeError as e:
        print("Login status is private: AttributeError")
elif test_case == "login_logout_sequence":
    # يتطلب هذا الاختبار توسيع الفئة باستخدام طريقة تسجيل الخروج
    # لأغراض الاختبار، سنقوم بإنشاء فئة فرعية مع وظيفة تسجيل الخروج
    class ExtendedMessenger(SecureMessenger):
        def logout(self):
            self._SecureMessenger__is_logged_in = False
            return "Logged out successfully"
    
    messenger = ExtendedMessenger("user7")
    print(messenger.login("secure123"))
    print(messenger.add_message("Test message"))
    print(messenger.get_messages())
    print(messenger.logout())
    print(messenger.get_messages())
elif test_case == "stress_test":
    # اختبار الضغط مع العديد من الرسائل
    messenger = SecureMessenger("user8")
    print(messenger.login("secure123"))
    
    # إضافة 100 رسالة
    for i in range(1, 101):
        messenger.add_message(f"Message {i}")
    
    # التحقق من عدد الرسائل
    messages = messenger.get_messages()
    newline_char = '\n'  # تخزين حرف السطر الجديد في متغير
    message_count = len(messages.split(newline_char))
    print(f"Added 100 messages. Retrieved {message_count} messages.")
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming