مقدمة
عادة ما يجد المبتدئون في البرمجة والمتحمسون الطموحون لهذا العالم الواسع صعوبة في فهم كيفية عمل لغة البرمجة ووظائفها، وما هي الأساليب والأدوات التي يجب أن يفهموها قبل أي شيء ، وكيفية تحسين التعليمات والمشاكل البرمجية، وفي هذا المقال سنشرح لماذا يجب عليك أن تتعلم وتفهم البرمجة الكائنية التوجه (OOP) بطريقة بسيطة ومقربة للواقع.
ماهي البرمجة الكائنية الموجهة على كل حال؟
نحتاج أولاً إلى معرفة أن النموذج البرمجي (مثل البرمجة الكائنية) هو أسلوب برمجة أو نهج أو فلسفة، فهو ليس تفاصيل صغيرة مثل البنية والجانب العملي المتعلق بلغة معينة. هناك 4 نماذج برمجة أساسية معروفة :
- إجرائية – Procedural : مثل لغات فورتران، C، باسكال ..
- وظيفية – Functional : مثل LISP، هاسكل..
- منطقية – Logical : مثل Prolog ،GHC..
- كائنية التوجه – Object-Oriented : مثل Smalltalk ، C ++ ، Java ، C # ، Python..
لماذا علي تعلم البرمجة الكائنية التوجه ؟
أول إجابة بديهية قد تحصل عليها من شخص في الميدان لأكثر من 5 سنوات هي : لأنها النموذج الأكثر طلبًا (من قبل العملاء والشركات) والمستخدم (من قبل المبرمجين والمطورين) اليوم ، بل إن استعمالها في أي مشروع برمجي اليوم أصبح عادة ولازمًا ما جعل بقية النماذج الأخرى من الماضي (باستثناء البرمجة الوظيفية).
لكن هذا ليس ما يريد الوافدون الجدد الذين لا يعرفون أي شيء عن البرمجة بشكل عام سماعه، لذلك من جانب الحياة اليومية، يساعدك فهم البرمجة الكائنية أيضًا على استيعاب قدر كبير من كيفية فهم وتحليل المشكلات و النظر إليها و تصميم حل لها. ومن أكثر الأشياء التي تجعل البرمجة الكائنية (OOP) المفضلة لدى غالبية المبرمجين هي تسهيلاتها عند التعامل مع البيانات (data) والوظائف (functions) ، حيث يعتبر البرنامج في الـ OOP بمثابة مجموعة <<كائنات>> تعمل معًا لتنفيذ مهمة، أين نهتم أولاً بالبيانات قبل تحديد الخوارزمية التي سيتم استخدامها للعمل مع هذه البيانات. تتعاون الكائنات بين بعضها البعض من خلال إرسال رسائل نسميها <<طرق (methods)>>.
ميزة إضافية تتميز بها الـ OOP على أنماط البرمجة الأخرى و هي <<مزايا التصميم>>، ومن المعروف للجميع أن البرامج الكبيرة يصعب كتابتها، فمصممو الـ OOP يجبَرون على المرور بمرحلة التخطيط الشاملة، مما يجعل التصاميم أفضل مع عيوب أقل. بالإضافة إلى ذلك، بمجرد أن يصل البرنامج إلى حجم معين، تصبح البرامج المعتمدة على البرمجة الكائنية أسهل في فهمها وتطويرها عن بقية النماذج.
الكائن – Object
تعتمد البرمجة الكائنية التوجه على مفهوم الكائن، في العالم الحقيقي يمكن أن يكون الكائن سيارة أو دولة أو أستاذا أو حاسوبا…هذه الأشياء لها ما نسميه بالسمات (attributes) والسلوكيات(behaviors).
الكائن | السمات | السلوك |
سيارة | مسرع | يتسارع |
مكتبة | المشتركون | قرض الكتب |
أستاذ | درس | يعلم |
حاسوب | معالج | يحسب |
يتم تعريف كل كائن بثلاث خصائص :
كائن= معرف+حالة+السلوك
√معرف – Identifier
كل كائن له معرف يميزه عن الأشياء الأخرى بشكل مستقل عن حالته وسلوكه. يمكن أن يكون لكائنين نفس الحالة والسلوك ولكن دائمًا معرف مختلف، والعكس بالعكس! يمكن تغيير سلوك وحالة الكائن أثناء تنفيذ البرنامج دون التأثير على المعرف.
√الحالة – State
تقدم لنا معلومات عن الكائن المحفوظ في المتغيرات (variables)، نسميها “سمات” أو “حقول”.
√السلوك – Behavior
هو مجموع المعاملات التي يمكن أن تغير من حالة الكائن وسماته.
√الصنف – Class
يمكن اعتبار صنف في البرمجة الكائنية بمثابة قالب أو نموذج يمكن من خلاله إنشاء كائنات، وستكون للكائنات التي تم إنشاؤها من نفس الصنف نفس الجوانب المتشابهة (نفس السمات والطرق)، ويسمى كائن صنف معين أيضًا “مثيل” من هذا الصنف.
شرح مبادئ البرمجة كائنية التوجه الأساسية:
هنالك أربعة! التغليف والتجريد والميراث والتعدد . قد تبدو هذه الكلمات مخيفة حتى لمطور صاعد، وكان هذا هو الحال بالنسبة لي، وأحيانًا قد تؤدي التفسيرات المعقدة والطويلة للغاية في الإنترنت إلى مضاعفة الإرتباك.لهذا السبب أريد أن أقدم شرحًا بسيطًا وقصيرًا وَ واضحًا لكلٍّ من هذه المفاهيم ، قد تبدو كشرح مقدمٍ لطفل.. ولكني أحب فعلًا سماع مثل هذه الإجابات إذا كنت في الجانب الآخر من السؤال.
*التغليف – Encapsulation
لنفترض أن لدينا برنامجًا يحتوي على عدد قليل من الكائنات المختلفة منطقيًا والتي تتواصل مع بعضها البعض وفقًا للقواعد المحددة سابقًا في البرنامج، يتم تحقيق التغليف عندما يحافظ كل كائن على حالته الخاصة، داخل صنف معين. لا تملك الكائنات الأخرى وصولا مباشرا إليها وبدلاً عن ذلك، يمكنهم فقط استدعاء قائمة بالوظائف العامة التي نسميها “طرق” كما ذكرنا من قبل.
إذا كنت ترغب في التواصل مع الكائن، فيجب عليك استخدام الطرق المقدمة ولكن بشكل افتراضي لا يمكنك تغيير الحالة. لتوضيح الأشياء دعونا نلعب لعبة، هناك أشخاص وهناك قطة، لتطبيق التغليف، نلخص كل منطق “القط” في صنف يسمى “القط”.
يحتوي صنف قطة على مجالات خاصة للمزاج والجوع والطاقة وطريقةَ “مواءٍ” خاصةٍ أثناء التغذية أما النوم واللعب فهي طرق عامة. يمكن للأصناف الأخرى الإتصال بها ولكن لا يمكنهم تعديل الطرق الخاصة مباشرة! بحيث يمكنك إطعام القطة ولكن لا يمكنك تغيير مدى جوعها هنا .
حالة القطة هي المتغيرات الخاصة من “المزاج” و”الجوع” و “الطاقة”. كما أن لديها طريقة خاصة “مواء”. ما يمكنهم القيام به هو الأساليب العامة للنوم واللعب والتغذية، وكل واحد منهم يعدل الحالات الداخلية وقد تستدعي هذه الطرق طرقا خاصة كالمواء مثلا.
هذا هو التغليف بكل بساطة !
*التجريد – Abstraction
يمكن اعتبار التجريد امتدادًا طبيعيًا للتغليف، غالبًا ما تكون برامج التصميم الكائنية التوجه كبيرة للغاية، بحيث تتواصل الكائنات المنفصلة مع بعضها البعض كثيرًا، لذلك فإن الحفاظ على قاعدة برنامج كبيرة مثل هذه لسنوات، ومع التغييرات والتحديثات أمر صعب للغاية، والتجريد هو مفهوم يهدف إلى حل أو التخفيف من هذه المشكلة.
يعني تطبيق التجريد أن كل كائن يجب أن يلج لمستوى أو جزء فقط من البرنامج، فكر في آلة صنع القهوة، هي تقوم بالكثير من الأشياء وتصدر الكثير من الضوضاء تحت غطاء المحرك ولكن كل ما عليك فعله هو وضع القهوة والضغط على زر .
يجب أن تكون هذه الآلية سهلة الإستخدام ونادرًا ما تتغير بمرور الوقت، فكر فيها كمجموعة صغيرة من الطرق العامة مثل تلك التي رأيناها في مثال القطة، والتي يمكن لأي فئة أخرى الإتصال بها دون معرفة كيفية عملها بالفعل.
مثال آخر حقيقي على التجريد؛ هو كيفية استخدام هاتفك، فالهواتف المحمولة معقدة ولكن استخدامها سهل وبسيط.
*التوريث – Inheritance
لقد رأينا كيف يمكن للتغليف والتجريد أن يساعدنا في تطوير والحفاظ على قاعدة تعليمات برمجية كبيرة، ولكن لا تزال هناك مشكلة شائعة أخرى في الـ OOP ، غالبًا ما تكون الكائنات متشابهة جدًا! يتشاركان المنطق المشترك لكنهما ليسا متشابهين تمامًا.
فكيف يمكننا إعادة استخدام المنطق المشترك لاستخراج المنطق الفريد في صنف منفصلة؟ طريقة واحدة لتحقيق ذلك من خلال التوريث.
يعني التوريث أنه يمكنك إنشاء صنف “تابع” من خلال اشتقاقها من صنف رئيسي آخر ، وبهذه الطريقة نشكل التسلسل الهرمي. وهي مبنية على أن الصنف الفرعي يعيد استخدام جميع سمات وطرق الصنف الأصل ويمكنه إضافة الجزء الفريد الخاص به ، على سبيل المثال:
*التعدد – Polymorphism
لقد وصلنا إلى الكلمة الأكثر تعقيدًا والتي نفسي وجدت صعوبة في فهمها أثناء دراستي الجامعية، تعدد الأشكال الذي يعني “العديد من الأشكال” في اليونانية.
عرفنا قوة التوريث وبإمكاننا الآن استعمالها بكل بساطة، ولكن تبقى لدينا مشكلة، لنفترض أن لدينا صنف أصلي وبعض الأصناف الفرعية التي ترثه، أحيانًا نريد استخدام مجموعة أو على سبيل المثال قائمة تحتوي على مزيج من جميع هذه الأصناف، أو لدينا طريقة منشأة في الصنف الأصلي ولكننا نرغب في استخدامها في الأصناف الفرعية أيضًا.
يمكن حل ذلك باستخدام التعدد، ببساطة! يعطي هذا الأخير طريقة لاستخدام صنف تمامًا مثل صنفه الأصلي بحيث لا يكون هناك التباس بخلط الأنواع ولكن كل صنف فرعي يحافظ على طرقه الخاصة كما هي.
يحدث هذا عادةً عن طريق تحديد واجهة (interface) صنف رئيسية ليتم إعادة استخدامها، وهي تحدد مجموعة من الطرق الشائعة. ثم يقوم كل فصل تابع بإضافة نسخته الخاصة من هذه الطرق.
في أي وقت تتوقع فيه مجموعة مثل القائمة أو الطريقة مثيلًا من الواجهة حيث يتم تحديد الطرق الشائعة، فإن اللغة تهتم بتقييم الإضافة الصحيحة للطرق الشائعة بغض النظر عن الفرع الذي تم تمريره.
قد يبدو من الصعب فهم التعدد من المرة الأولى، لكن المثال التالي جعله واضحًا بالنسبة لي، ألقِ نظرة على المثال التالي لتعدد الأشكال الهندسية، حيث تعيد هذه الأشكال استخدام واجهة مشتركة لحساب مساحة السطح والمحيط :
-يتيح لك وجود هذه الأشكال الثلاثة التي ترث الفرع الأصلي <<واجهة الشكل>> إنشاء قائمة بالمثلثات والدوائر والمستطيلات المختلطة ومعاملتها مثل نفس نوع الكائن.
بعد ذلك ، إذا حاولت هذه القائمة حساب سطح عنصر، يتم تلقائيا العثور على الطريقة الصحيحة وتنفيذها بحيث تُستدعى طريقة “CalculateSurface” للمثلث و التي قمنا بإضافتها إذا كان الشكل مثلثا، أما إذا كان دائرة فتستدعى الطريقة الخاصة بالدائرة وهكذا دواليك. إذا كان لديك طريقة تعمل مع أي شكل باستخدام السمات الخاصة به، فليس عليك تعريفها في كل صنف، مرة واحدة لكل من المثلث والدائرة والمستطيل، يمكنك تعريفها مرة واحدة وإضافة متغير “شكل ” لتحديد الشكل، لذلك سواء قمت بتمرير مثلث أو دائرة أو مستطيل ، وطالما أنها تقوم بتطبيق “CalculateSurface“، فلا يهم نوعها!
ماذا بعد؟
لا يكفي فهم البرمجة الكائنية التوجه نظريًا فقط ، أنت بحاجة إلى الممارسة وللقيام بهذا تحتاج إلى بدء تعلم اللغات التي تعتمد على هذا النموذج الحديث مثل Java و Python و C ++. وبمجرد أن تبدأ في تدريب نفسك على المشاريع الصغيرة أو القوالب وتتعلم حيلا جديدة تكسبك خبرات وترسخ في ذهنك هذه المفاهيم سيبدو لك كل شيء بسيط وله معنى.
إعداد: مسفاك عده.
تدقيق لغوي: كعبوب أسماء.
تصميم: رامي نزلي.
Discussion about this post