مدخل إلى جافا مفهوم الكائنات Objects والبرمجة كائنية التوجه OOP


Rama Alkhayer

يجب إجراء تصميم للبرامج، فلا يمكن لأحدٍ أن يجلس ببساطةٍ أمام الحاسوب ويُؤلف برنامجًا معقدًا. يُهتَّم فرع هندسة البرمجيات (software engineering) ببناء برامج صحيحة، فعَّالة ومكتوبة على نحوٍ سليم. يحاول مهندس البرمجيات استخدام أساليب مقبولة ومُثبتة لتحليل المسألة لكي يتم حلها ومن ثم تصميم برنامج لحل تلك المسألة.

خلال سبعينيات وبداية ثمانينيات القرن الماضي، كانت المنهجية الأساسية في هندسة البرمجيات هي "البرمجة البنيوية" (structured programming). يعتمد أسلوب البرمجة البنيوية لتصميم البرامج على النصيحة الآتية: لحل مسألة ضخمة، جزِّئها إلى عدة أجزاء ثم اعمل على كلّ جزءٍ على حدة. لحل كل جزء، عالجه كما لو مسألةً جديدة يمكن أن تُجزّأ بدورها إلى مسائل أصغر. ستصل في نهاية المطاف إلى مسائل يُمكن حلّها مباشرةً بدون تفكيكها. يُدعى هذا الأسلوب بالبرمجة التنازلية (top-down programming) أي منهج من الأعلى إلى الأسفل.

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

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

لذا، يُدمج التصميم التنازلي غالبًا في الممارسة العملية مع التصميم التصاعدي (bottom-up design) أي من الأسفل إلى الأعلى. في التصميم التصاعدي، تبدأ من الأسفل بمسائل تعرف مسبقًا كيفية حلها (وقد يكون لديك في متناول يدك مُكوّن برمجي قابل لإعادة الاستخدام فيها). من هناك، تستطيع العمل تصاعدياً نحو حلّ للمسألة الكلية.

ينبغي أن تكون المكونات القابلة لإعادة الاستخدام "مقولبة" قدر الإمكان. الوحدة (module) هي إحدى مكونات نظام ضخم تتفاعل مع بقية النظام بأسلوب بسيط، واضح المعالم ومباشر. تكمن الفكرة في إمكانية "وصل" الوحدة بالنظام. لا يهتم النظام ككل بالتفاصيل التي تجري داخل الوحدة طالما أن الوحدة تؤدي الدور الذي أُسند لها على نحوٍ صحيح. يُدعى هذا بإخفاء المعلومات (information hiding) وهو أحد أهم مبادئ هندسة البرمجيات.

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

أصبحت الوحدات التي تستطيع دعم هذا النوع من تخبئة المعلومات واسعة الانتشار بين لغات البرمجة في بداية ثمانينيات القرن الماضي. منذ ذلك الحين، سيطرت صيغة أكثر تقدمًا من الفكرة ذاتها على هندسة البرمجيات. يُدعى هذا الأسلوب الأخير بالبرمجة كائنية التوجه (object-oriented programming، وغالبًا ما يختصر إلى OOP).

يتمحور مفهوم البرمجة كائنية التوجه حول الكائن (object)، والذي يمثِّل نوعًا من الوحدات التي تتضمن بيانات وبرامج فرعية. وجهة النظر في البرمجة كائنية التوجه هي أن الكائن هو كيان مُكتفٍ ذاتيًّا فلديه حالة (state) داخلية (هي البيانات التي يتضمنها) وقادر على الاستجابة للرسائل (استدعاءات البرامج الفرعية الموجودة ضمنه). يتضمن كائن قائمة المراسلات البريدية على سبيل المثال حالةً تتألف من قائمة من الأسماء والعناوين. إذا أرسلت له رسالة تُخبره فيها بإضافة اسم، يستجيب عبر تعديل حالته لتعكس التغيير الذي طلبته. إذا أرسلت له رسالة تخبره فيها بطباعة نفسه، يستجيب عبر طباعة قائمته من الأسماء والعناوين.

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

ربما تظن أن الكائنات تعرف كيف تستجيب لرسائل بعينها. قد تستجيب الكائنات المختلفة إلى نفس الرسالة بطرائق مختلفة. على سبيل المثال، فقد ينتج عن الرسالة "طباعة" نتائج مختلفة كليًا وفق الكائن الذي تُرسَل إليه. تدعى هذه الخاصية التي تسمح للكائنات المختلفة بالاستجابة لنفس الرسالة بطرائق مختلفة بالتعدديّة الشكلية (polymorphism).

من الشائع أن تشترك الكائنات بسماتٍ أو "تشابه عائلي". تنتمي الكائنات التي تحتوي النوع نفسه من البيانات وتستجيب للرسائل نفسها بالطريقة نفسها إلى صنف (class) واحد. (في البرمجة الفعلية، يكون الصنف نوعًا أوليًّا، أي أنَّنا ننشئ صنفًا ومن ثم يُنشَأ كائن أو أكثر بالاعتماد على ذاك الصنف بعدِّه قالبًا). لكن يمكن للكائنات أن تكون متشابهةً بدون أن تكون مشتقة كم الصنف نفسه تمامًا.

على سبيل المثال، تخيّل برنامج رسمٍ يسمح للمستخدم برسم خطوط، ومستطيلات، وأشكال بيضوية، ومضلّعاتٍ، ومنحنيات على الشاشة. يمكن تمثيل كل كائن مرئي على الشاشة بكائن برمجي في البرنامج. سيتضمن البرنامج خمسة أصناف من الكائنات، يقابل كلٌّ منها نوعًا من الكائنات المرئية التي يمكن رسمها. ستتبع جميع الخطوط إلى صنف واحد، وجميع المستطيلات إلى صنف آخر مختلف، وقس على ذلك. ثمة بوضوح قرابة بين تلك الأصناف حيث تمثل جميعها "كائنات قابلة للرسم". من المتوقع على سبيل المثال أن تستجيب جميع هذه الأصناف إلى رسالة "ارسم نفسك".

هناك مستوى آخر للتجميع يعتمد على البيانات اللازمة لتمثيل كل نوع من الكائنات. هذا المستوى، وإن كان أقل بديهية إلا أنه مفيد جدًا في البرنامج. يمكننا تجميع المضلعات والمنحنيات معًا ضمن "كائنات متعددة النقاط"، بينما تندرج الخطوط والمستطيلات والمنحنات ضمن "كائنات ذات نقطتين." (يُحدد الخط بنقطتين تمثلان نهايتيه، والمستطيل باثنتين من زواياه، والمنحني بزاويتين من المستطيل الذي يحتويه. نتحدث عن المستطيلات ذات الأضلاع العمودية والأفقية والتي يمكن تحديدها بنقطتين فقط. وهذا هو المعنى الشائع لكلمة مستطيل في برامج الرسم.) يمكننا تمثيل هذه العلاقات بالرسم البياني التالي:

overview-fig4.png

يُمثل كلّ من "الكائن القابل للرسم" DrawableObject، و"الكائن متعدد النقاط" MultipointObject و"الكائن ثنائي النقاط" TwoPointObject أصنافًا في البرنامج. يكون كلّ من "الكائن متعدد النقاط" MultipointObject و"الكائن ثنائي النقاط" TwoPointObject صنفين فرعيين من "الكائن القابل للرسم" DrawableObject. يمثّل الصنف "خط" Line صنفًا فرعيًا من الصنف TwoPointObject "الكائن ثنائي النقاط" وعليه (على نحوٍ غير مباشر) من الصنف DrawableObject "كائن قابل للرسم". يُقال أنّ الصنف المتفرِّع من صنف ما يرث صفات ذاك الصنف. يمكن للصنف الفرعي أن يضيف على ما ورثه من أبيه، ويمكنه حتى أن يعيد تعريف جزء مما ورثه (عبر تعريف استجابة مختلفة لبعض الرسائل). على أية حال، تُمثَّل الخطوط والمستطيلات وما إلى هنالك كائنات قابلة للرسم ويعبر الصنف DrawableObject "كائن قابل للرسم" عن هذه العلاقة.

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

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

ترجمة وبتصرف للفصل Objects and Object-oriented Programming من كتاب Introduction to Programming Using Java





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن