AudaNix

8.4. دوال الوصول والتغليف

1 مشاركة في هذا الموضوع

دوال الوصول والتغليف Access functions and encapsulation

دوال الوصول Access functions

دالة الوصول هى دالة عامة صغيرة التى وظيفتها ارجاع قيمة المتغير الخاص العضو . علي سبيل المثال فى فئة النصوص التى اوضحنا فكرتها فى نهاية الدرس السابق، فيكن صياغة كود لها كالتالي:

class String
{
private:
char *m_chString; // حجز سلسلة نصية بشكل آلى
int m_nLength; // طول الــ m_chString

public:
int GetLength() { return m_nLength; }
}

بكل بساطة فأن دالة الوصول GetLength() ترجع قيمة المتغير m_nLength.

دوال الوصول بشكل اساسي تأتي فى صورتين ام ارجاع getters او ضبط setters . دوال ارجاع القيمة Getters هى دوال عادية ترجع قيمة المتغير العضو الخاص بالفئة. ودوال الضبط setters هي دالة عادية تقوم بتعيين قيمة للمتغير الخاص العضو بالفئة.

مثال:

class Date
{
private:
int m_nMonth;
int m_nDay;
int m_nYear;

public:
// Getters ارجاع
int GetMonth() { return m_nMonth; }
int GetDay() { return m_nDay; }
int GetYear() { return m_nYear; }

// Setters ضبط
void SetMonth(int nMonth) { m_nMonth = nMonth; }
void SetDay(int nDay) { m_nDay = nDay; }
void SetYear(int nYear) { m_nYear = nYear; }
};

قد تقول لما كل هذا العناء ان تجعل المتغير العضو خاص ثم تقوم بعمل دالة وصول عامة سواء تضبط او ترجع قيم اليه؟ اﻻجابة هى مفهوم التغليف encapsulation .

التغليف Encapsulation

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

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

فى سي++ محددات الوصول تسمح لك بتطبيق مفهوم التغليف بداخل الفئات. وهذا عادا يحدث بعمل كل المتغيرات الاعضاء فى الفئة متغيرات اعضاء خاصة، وأضافة دوال عامة (غالباً دوال وصول) تسمح للمستخدم للعمل مع هذة الفئة. ورغم أن ذلك يبدو أمرا متعبا من السماح بالوصول المباشر بشكل عامل ، ان فعل ذلك حقيقا يعطينا الكثير من الفوائد التى تساعد فى اعادة استخدام وصيانة الفئة.

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

ألق نظرة على الكود التالي:

class Change
{
public:
int m_nValue;
};

int main()
{
Change cChange;
cChange.m_nValue = 5;
std::cout << cChange.m_nValue << std::endl;
}

سيظل هذا البرنامج يعمل بنجاح. لكن ماذا ان يحدث ان قررت اعادة تسمية المتغير m_nValue ؟ فأن ذلك يتسبب فى توقف البرنامج!! التغليف يعطينا امكانية تغيير فئتنا الجميلة بدون ان يتوقف الكود عن العمل .

التالى نسخة مغلفة من تلك الفئة تستخدم دوال الوصول للحصول على قيمة m_nValue :

class Change
{
private:
int m_nValue;

public:
void SetValue(int nValue) { m_nValue = nValue; }
int GetValue() { return m_nValue; }
};

int main()
{
Change cChange;
cChange.SetValue(5);
std::cout << cChange.GetValue() << std::endl;
}

الآن عندما نقرر تغيير اسم الــ m_nValue نحن بحاجة الى القليل من الكود بداخل SetValue() و GetValue() لكي تتوافق مع التغييرات. وتذكر ان برنامج لايحتاج الي تغيير بشكل كامل.

ثانياً، اخفاء تفاصيل كيفية تطوير الفئة هذا يعنى ان المبرمج ممكن يستخدم الفئة بدون ان يعرف كيف تم برمجتها. هذا يقلل الوقت لتعلم كيفية استخدام الفئة وتكون الفئة اسهل فى التعامل معها.

ثالثا، التغليف يساعد على منع التغييرات غير المقصودة وسوء الاستخدام. لان المتغيرات الاعضاء لايمكن الوصول اليها بشكل مباشر، هذا يساعد على منع التغير غير المقصود في القيم. وبالاضافة الى ذلك غالبا تكون المشكلة عن تغيير قيمة ما فأن القيم الاخر ايضا تحتاج الى تحديث قيمتها. على سبيل المثال فى فئة نصية عند تغير السلسلة النصية فأن المتغير الذي يحمل طول السلسلة النصية يجب تحديث قيمة. لو ان المستخدم لة حق الوصول المباشر الى السلسلة النصية فأنة قد ينسي تحديث المتغير الذي يحمل طول السلسلة النصية عند تغيير السلسلة النصية. فأن دالة واجهة المستخدم تسمح للمستخدم بتغيير السلسلة النصية وتحديث متغير طول السلسلة النصية بشكل آلي كلما حدث تغيير وهذا يعنى ان لمستخدم لايقلق ابدا المتغير الذي يحمل طول السلسلة النصية(فكر فى الامر لو لدينا 60 متغير يجب تحديثم كل حدث تغيير!!! ).

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

كما تري يعطى التغليف الكثير من المميزات بقليل من المجهود. وخصوصا امكانية تغيير تفاصيل كود تطوير الفئة بدون التأثير على اي برنامج يستخدم الفئة وهى اعلى درجات معالجة الكود.

الدرس التالي: 8.5. دالة بناء الفئة

أذهب الي:المقدمة والفهرس الرئيس

الدرس السابق: 8.3. محددات الوصول العامة والخاصة

تم تعديل بواسطه محمد عودة
تنسيقات لتحسين العرض وتنقيح الترجمة
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .