إخفاء المعلومات
جزء من قسم 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). يمنع هذا التلاعب المباشر بالبيانات الحساسة ويضمن سلامة البيانات من خلال التحقق من الصحة في طرق الوصول.
التحدي
متوسطفي هذا التحدي، ستقوم بتنفيذ نظام مراسلة آمن مع اختبار شامل للتحقق من صحة الحل الخاص بك.
تحتاج إلى تعديل 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.")يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsمعامل selfMethodsAttributesدالة البناء (__init__)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةدالة ()superإعادة تعريف الدوال (Method Overriding)الوراثة المتعددةترتيب استدعاء الدوال (Method Resolution Order)مراجعة - هيكلية الموظفين5تعدد الأشكال
مراجعة إعادة تعريف الدوالمفهوم Duck Typingالأصناف والدوال المجردةتصميم الواجهاتملخص - حاسبة الأشكال3خصائص الـ Class
متغيرات الـ Instance مقابل متغيرات الـ ClassProperty Decoratorsالسمات الخاصةمراجعة - مدير الحساب البنكي6التغليف (Encapsulation)
الأعضاء العامة والمحمية والخاصةمحددات الوصولإخفاء المعلوماتProperty Decorators متقدمةمراجعة - نظام سجلات الطلاب