🛡️ فهم التغليف (Encapsulation) في بايثون: حماية بياناتك البرمجية

التغليف هو أحد الركائز الأساسية في البرمجة كائنية التوجه (OOP) والذي يعني "تغليف" البيانات والوظائف المرتبطة بها معاً داخل كائن واحد. فكر فيه ككبسولة تحمي محتوياتها الداخلية من التدخل الخارجي المباشر.


🎯 ما هو التغليف ولماذا نستخدمه؟

التغليف (Encapsulation) يعني جمع البيانات (الخصائص) والوظائف (الطرق) التي تعمل على هذه البيانات داخل وحدة واحدة تسمى "الفئة" (Class). الهدف الرئيسي هو:

  • حماية البيانات: منع الوصول المباشر غير المرغوب فيه للبيانات
  • إخفاء التفاصيل: إظهار الواجهة فقط وإخفاء التعقيد الداخلي
  • التحكم في البيانات: فرض قيود على كيفية تعديل البيانات
class BankAccount:
    def __init__(self, initial_balance):
        self._balance = initial_balance  # بيانات محمية
    
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
    
    def get_balance(self):
        return self._balance

# الاستخدام
account = BankAccount(1000)
account.deposit(500)
print(account.get_balance())  # 1500

🔒 مستويات الوصول في التغليف

في بايثون، نستخدم اصطلاحات تسمية للإشارة إلى مستوى الوصول:

المتغيرات العامة (Public)

  • يمكن الوصول لها من أي مكان
  • تبدأ باسم عادي: name, balance

المتغيرات المحمية (Protected)

  • للاستخدام الداخلي وفي الفئات الفرعية
  • تبدأ بشرطة سفلية واحدة: _balance, _name

المتغيرات الخاصة (Private)

  • للاستخدام الداخلي فقط
  • تبدأ بشرطتين سفلية: __balance, __password
class Student:
    def __init__(self, name, age):
        self.name = name          # عام
        self._age = age           # محمي
        self.__gpa = 3.5          # خاص
    
    def get_gpa(self):
        return self.__gpa

student = Student("أحمد", 20)
print(student.name)     # ✅ مسموح
print(student._age)     # ⚠️ غير مستحب
# print(student.__gpa)  # ❌ خطأ - لا يمكن الوصول مباشرة

🛠️ استخدام الخصائص (Properties) للتحكم في البيانات

الخصائص (Properties) تتيح لنا التحكم في كيفية قراءة وتعديل البيانات باستخدام دوال Getter وSetter.

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
    
    @property
    def celsius(self):
        """Getter للدرجة المئوية"""
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        """Setter للدرجة المئوية مع التحقق"""
        if value < -273.15:
            raise ValueError("لا يمكن أن تكون درجة الحرارة أقل من -273.15")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        """خاصية محسوبة للفهرنهايت"""
        return (self._celsius * 9/5) + 32

# الاستخدام
temp = Temperature(25)
print(temp.celsius)      # 25
print(temp.fahrenheit)   # 77.0

temp.celsius = 30        # ✅ مسموح
# temp.celsius = -300    # ❌ سيسبب خطأ

💡 مثال عملي: نظام إدارة الموظفين

لنطبق مفهوم التغليف على مثال واقعي:

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self._salary = salary
        self.__bonus = 0
    
    @property
    def salary(self):
        return self._salary
    
    @salary.setter
    def salary(self, value):
        if value < 0:
            raise ValueError("الراتب لا يمكن أن يكون سالباً")
        self._salary = value
    
    def calculate_bonus(self, performance_rating):
        """حساب المكافأة بناءً على الأداء"""
        if performance_rating >= 90:
            self.__bonus = self._salary * 0.2
        elif performance_rating >= 70:
            self.__bonus = self._salary * 0.1
        else:
            self.__bonus = 0
        return self.__bonus
    
    def get_total_income(self):
        """الحصول على إجمالي الدخل (الراتب + المكافأة)"""
        return self._salary + self.__bonus

# الاستخدام
emp = Employee("سارة", 5000)
emp.calculate_bonus(95)
print(f"إجمالي الدخل: {emp.get_total_income()}")  # 6000

✅ فوائد التغليف في البرمجة

  1. الأمان: حماية البيانات من التعديل غير المسموح
  2. المرونة: يمكن تغيير التطبيق الداخلي دون التأثير على المستخدمين
  3. سهولة الصيانة: الكود أكثر تنظيماً وأسهل في الفهم
  4. التحقق من الصحة: يمكن التحقق من صحة البيانات قبل تعيينها