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

ما هو التغليف (Encapsulation)؟

في البرمجة كائنية التوجه، التغليف (encapsulation) هو جمع بيانات الكائن والدوال التي تعمل عليها في وحدة واحدة، هي الصنف (class) عادةً، وإخفاء التفاصيل الداخلية بحيث لا يستطيع الكود الآخر استخدام الكائن إلا عبر دواله العامة.

بقلم Kevin Spektor, شريك مؤسس ورئيس قسم التكنولوجيا (CTO)

آخر تحديث 24 سبتمبر 2026

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

كيف يعمل التغليف

يجمع التغليف بين فكرتين:

  1. التجميع. البيانات (الرصيد) والكود الذي يعمل عليها (الإيداع والسحب) يعيشان في الصنف نفسه.
  2. الإخفاء. لا يرى الكود الآخر إلا الواجهة العامة للصنف. البيانات التي خلفها داخلية، فلا تتغيّر إلا بالطرق التي يسمح بها الصنف.

القاعدة التي يحميها الصنف تسمى الثابت (invariant): هنا "الرصيد لا يكون سالبًا أبدًا". ولأن كل تغيير يمر عبر دوال الصنف، يبقى الثابت صحيحًا مهما فعل باقي البرنامج.

70
refused: not enough money

يستطيع الكود الخارجي قراءة acct.balance، لكن الخاصية (property) ليس لها setter، فكتابة acct.balance = 1000 ترفع AttributeError. وإن كان الرصيد خاطئًا يومًا ما، فهناك دالتان بالضبط يجب فحصهما.

التغليف في بايثون

ليس في بايثون كلمة محجوزة اسمها private. بل تعتمد على اصطلاحات تسمية يعرفها كل مبرمج بايثون:

  • name: عام، جزء من الواجهة.
  • _name: داخلي. لا شيء يمنعك من قراءته، لكن الشرطة السفلية في بدايته تقول "لا تعتمد على هذا".
  • __name: تعيد بايثون تسميته داخل الصنف (name mangling)، فلا يستطيع صنف فرعي الكتابة فوقه عن طريق الخطأ.
  • @property: تحوّل دالة إلى شيء يُقرأ كأنه سمة، فتستطيع إضافة فحوص لاحقًا دون تغيير أي كود يستدعيها.
0
False
42

إعادة التسمية تمنع الحوادث لا الوصول: فالاسم المُعاد تسميته لا يزال يعمل. تثق بايثون بأن المبرمجين سيحترمون الشرطة السفلية. وفي الواقع يستخدم معظم كود بايثون شرطة سفلية واحدة مع @property، ويحتفظ بالشرطتين للأصناف المصممة ليُورَث منها. والمزيد عن كتابة الأصناف في توثيق الأصناف في بايثون.

التغليف في جافا و C++ وجافا سكريبت

لغات أخرى تفرض الإخفاء فرضًا. في جافا لا يمكن استخدام الحقل private إلا داخل صنفه:

public class BankAccount {
    private int balance;  // hidden from every other class

    public int getBalance() { return balance; }

    public void withdraw(int amount) {
        if (amount > balance) throw new IllegalArgumentException("not enough money");
        balance -= amount;
    }
}

كتابة account.balance = 1000; في صنف آخر لا تُترجم: يُبلغ javac عن balance has private access in BankAccount.

اللغةالعضو المخفيالعضو العاممن يفرضه
بايثون_name و__namenameالاصطلاح
جافاprivate int namepublic int nameالمترجم
C++قسم private:قسم public:المترجم
جافا سكريبت#namenameمحرك جافا سكريبت

تجعل C++ أعضاء class خاصة افتراضيًا وأعضاء struct عامة. وحقول # الخاصة في جافا سكريبت، التي أُضيفت في ES2022، لا يمكن قراءتها من خارج الصنف إطلاقًا. يغطي التوثيق كلًا منها: معدِّلات الوصول في جافا، ومحددات الوصول في C++، والحقول الخاصة في جافا سكريبت.

لماذا التغليف مهم

  • القواعد تعيش في مكان واحد. فحص "لا سحب يتجاوز الرصيد" يُكتب مرة واحدة داخل withdraw، بدل كتابته قبل كل عملية سحب في البرنامج.
  • يمكنك تغيير الداخل بحرية. إن قررت تخزين المال بالسنتات الكاملة بدل عدد عشري، فالصنف وحده يتغيّر. والكود الذي يستدعي deposit(100) يستمر في العمل.
  • تنقيح أسهل. حين تكون قيمة ما خاطئة، فالمشتبه بهم هم الدوال القليلة المسموح لها بتغييرها، لا كل سطر في البرنامج.
  • أقل للتعلم والاختبار. صنف له ثلاث دوال عامة يمكن فهمه واختباره عبر تلك الدوال الثلاث.

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

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

أخطاء شائعة

  • getter و setter لكل حقل. الدالة setBalance التي تقبل أي رقم لا تحمي شيئًا. قدّم العمليات التي يحتاجها الكائن (withdraw)، لا وصولًا خامًا إلى كل حقل.
  • إرجاع الكائنات الداخلية. الدالة التي تُرجع self._items تسلّم المستدعي القائمة الحقيقية، فيصبح قادرًا على تغييرها. أرجِع نسخة أو tuple بدلًا من ذلك.
  • معاملة الخاص على أنه أمان. معدِّلات الوصول تمنع الأخطاء لا الهجمات. يستطيع كود جافا قراءة الحقول الخاصة عبر الانعكاس (reflection)، ويستطيع كود بايثون قراءة _name مباشرة. كلمات المرور والمفاتيح تحتاج إلى حماية حقيقية، مثل التجزئة (hashing) والتشفير.

إلى أين بعد ذلك

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

الأسئلة الشائعة

ما هو التغليف بعبارات بسيطة؟
التغليف يعني أن الكائن يحتفظ ببياناته لنفسه ويقدّم بضع طرق آمنة لاستخدامها. كائن الحساب البنكي لا يسمح لك بكتابة رصيد جديد مباشرة، بل يعطيك deposit وwithdraw اللتين تفحصان القواعد أولًا. والاسم الإنجليزي مأخوذ من الكبسولة (capsule)، وهي غلاف يحفظ محتوياته في داخله.
ما هي أمثلة التغليف؟
صنف الحساب البنكي الذي لا يسمح بالتغييرات إلا عبر deposit وwithdraw هو المثال الكلاسيكي. والنوع list في بايثون نفسها مثال آخر: تستدعي append ولا تدير أبدًا الذاكرة التي تخزّن العناصر. والوحدة (module) التي تكشف بضع دوال وتُبقي دوالها المساعدة خاصة هي تغليف على نطاق أوسع.
ما هي أنواع التغليف الثلاثة؟
الدروس التي تسرد ثلاثة أنواع تقصد عادةً تغليف المتغيرات الأعضاء (الحقول الخاصة)، وتغليف الدوال (الدوال المساعدة الخاصة)، وتغليف الأصناف (صنف مخفي داخل صنف آخر أو وحدة). هذه ليست تصنيفات رسمية، بل هي الفكرة نفسها مطبقة على الحقول والدوال والأصناف الكاملة.
ما هو التغليف في C++ وكيف يُستخدم؟
في C++ تحدد أعضاء البيانات بـ private وتوفر دوالًا أعضاء public تقرؤها أو تغيّرها. أعضاء class خاصة افتراضيًا، بينما أعضاء struct عامة افتراضيًا. ويرفض المترجم أي كود خارج الصنف يحاول استخدام عضو خاص.
ماذا يعني التغليف في الشبكات؟
في الشبكات، التغليف يعني لفّ البيانات بترويسات كل طبقة من طبقات البروتوكول في طريقها إلى الخارج: رسالة HTTP توضع داخل مقطع TCP، الذي يوضع داخل حزمة IP، التي توضع داخل إطار Ethernet. يشترك في الاسم مع فكرة البرمجة لكنه مفهوم مختلف.
Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن