الجزء 2 - WordPress والبرمجة الموجهة للكائنات: مثال من العالم الحقيقي

نشرت: 2021-07-29

في نظرة عامة على WordPress والبرمجة الموجهة للكائنات ، استعرضنا النظرية الكامنة وراء البرمجة الموجهة للكائنات (OOP) وما يمكن توقعه عند استخدامها.

قبل المضي قدمًا في أمثلة الترميز الأكثر تحديدًا باستخدام OOP ، سنحاول في هذه المقالة شرح كيفية التعامل مع سيناريو العالم الحقيقي بالعقلية المختلفة المطلوبة لـ OOP وكيف يتم تحليل ذلك باستخدام الكائنات والفئات.

سيناريو حقيقي: إرسال رسالة نصية قصيرة

هذا يشبه إلى حد كبير ، سيناريو الحياة "الماضية" في الواقع حيث يتم استخدام الرسائل القصيرة بشكل أقل وأقل في الوقت الحاضر ولكن كما سترى ، هناك سبب لاستخدامنا هذا كمثال!

افترض أن لديك جهازًا محمولاً وتريد إرسال رسالة نصية إلى أحد جهات الاتصال الخاصة بك. بأبسط مثال ممكن ، سيكون تسلسل الإجراءات كما يلي:

  1. جهز الرسالة
  2. حدد إحدى جهات الاتصال الخاصة بك وأضفها كمستلم
  3. أرسل الرسالة

لذلك دعونا نحاول تصور الخطوات التي ستتبعها لإرسال رسالتك:

أضفنا بعض الأوصاف الأكثر تفصيلاً للإجراءات ولكن كل ما تفعله أكثر أو أقل هو 3 خطوات أساسية. تقوم بإعداد الرسالة في محرر الجهاز ، وتحدد المستلم من جهات الاتصال الخاصة بك ، ثم ترسل الرسالة. وانت انتهيت! تم إرسال رسالتك الآن.

الآن ، إذا أردنا تمثيل تطبيق يرسل رسالة SMS في الكود ، فيجب علينا تحليل المسار الذي من الأفضل اتباعه ؛ النهج الإجرائي أو OOP.

التطبيق مع نهج إجرائي

إذا كنت مطورًا لمكوِّن إضافي لبرنامج WordPress ، فمن المرجح أن تكون على دراية بالبرمجة الإجرائية .

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

في مثالنا أعلاه مع رسالة SMS ، ستقوم بتنفيذ سلسلة من الإجراءات التي من شأنها أن تؤدي إلى النتيجة المرجوة. كما قد تكون خمنت بالفعل ، سيكون لديك ، على سبيل المثال ، متغير يحتوي على محتوى نص الرسالة ، ووظيفة مع معلمة $contact التي تُرجع رقم الهاتف ، وأخيراً وظيفة ترسل الرسالة. في الكود سيبدو كما يلي:

 function get_phone_number( $contact ) { // Code that finds the contact's number in the list of contacts return $phone_number; } function send_sms( $contact, $message ) { $phone_number = get_phone_number( $contact ); // Code that sends the message to this number print "Message Sent!"; }

ويمكنك استخدامه على النحو التالي:

 $text = "Hello John"; function send_message( "John Doe", $text );

لذلك ، ستكمل سلسلة من المهام التي ستقودك إلى النتيجة المرجوة.

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

توسيع التطبيق مع النهج الإجرائي

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

عند إرسال بريد إلكتروني ، فإنك تحتاج إلى عنوان البريد الإلكتروني لجهة الاتصال ، وليس رقم الهاتف. بصرف النظر عن هذا ، سنحتاج إلى إضافة معلمة في وظيفة send_message() النهائية تتوافق مع نوع التقنية التي نستخدمها ؛ البريد الإلكتروني أو الرسائل القصيرة.

يمكن أن يبدو الرمز المقابل كما يلي:

 function get_phone_number( $contact ) { // Code that finds the contact's number return $phone_number; } function get_email_address( $contact ) { // Code that finds the contact's email address return $email_address; } function send_sms( $contact, $message ) { $phone_number = get_phone_number( $contact ); // Code that sends the message to this number print "SMS Sent!"; } function send_email( $contact, $message ) { $email_address = get_email_address( $contact ); // Code that sends the email to this number print "Email Sent!"; } function send_message( $contact, $message, $technology ) { if ( $technology == "SMS") { send_sms( $phone_number, $message ); } else if ( $technology == "Email") { send_email( $email_address, $message ); } }

لذا ، فالأمر ليس كذلك لا يمكن تنفيذه بنهج إجرائي. ولكن إذا كنت مطورًا متمرسًا ، فربما تكون قد فهمت بالفعل كيف يمكن أن يصبح هذا الأمر فوضويًا في المستقبل.

العيوب مع منهج إجرائي

ماذا لو كان لدينا أنواع متعددة من الرسائل؟ سوف تصبح عبارات if كبيرة بشكل مزعج. والأهم من ذلك ، ماذا لو كان لديك وظائف تستخدم وظيفة send_message() ؟ في هذه الحالة ، ستحتاج إلى إضافة معلمة $technology في جميع هذه الوظائف أيضًا.

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

استضافة موقع الويب الخاص بك مع Pressidium

ضمان استرداد الأموال لمدة 60 يومًا

اطلع على خططنا

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

كائن يحتوي على بيانات ورمز. لا يزال لدينا متغيرات يمكنها تخزين المعلومات ، تسمى الخصائص . والإجراءات التي تعمل على البيانات تسمى الأساليب .

التطبيق مع نهج OOP

الآن دعنا نحلل نفس السيناريو على النحو الوارد أعلاه باستخدام نهج OOP.

أولاً ، سنحدد ما هي الأشياء التي لدينا هنا ، وما هي الخصائص التي يمتلكها كل منها وما هي الإجراءات التي يؤدونها. الخصائص هي ما ستكون خصائصنا وأفعالنا ستكون وظائفنا أو أساليبنا كما يطلق عليها في OOP.

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

 <?php /** * Plugin Name: Send Message */ interface MessagingCapable { public function send_message( $contact, $message ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print "You sent" . $message ; } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); }

نعلن عن فئة Phone التي تنفذ واجهة MessagingCapable . لذلك علينا أن نطبق كل الأساليب المعلنة فيه. تتطلب وظيفة say_hi() 3 معلمات:

  1. جهاز يدعم المراسلة
  2. اتصال
  3. الرسالة

من أجل إرسال رسالة فعليًا ، نستخدم هذه الوظيفة على النحو التالي:

 $phone = new Phone(); say_hi( $phone, "John Doe", "Hello John" );

نحن نقوم بشكل أساسي بإنشاء كائن عن طريق إنشاء فئة الهاتف وتمرير محتوى جهة الاتصال والرسائل. هذا من شأنه أن ينتج:

 You sent "Hello John"

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

توسيع التطبيق باستخدام نهج OOP

دعنا نضيف القدرة على إرسال رسائل البريد الإلكتروني أيضًا ، كما فعلنا من قبل من الناحية الإجرائية.

بغض النظر عن الجهاز ، نود استخدام say_hi() بنفس الطريقة. ألق نظرة على الكود أدناه:

 <?php /** * Plugin Name: Send Message */ interface MessagingCapable { public function send_message( $contact, $message ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" SMS to ' . $contact ); } } class Computer implements MessagingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" email to ' . $contact ); } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); }

عندما نستخدم هذا الجزء من الرمز ، فإننا نلتقط الجهاز المحمول لإرسال رسالة نصية قصيرة والكمبيوتر لإرسال بريد إلكتروني. نود إما:

 say_hi ( new Phone(), "John Doe", "Hello John" );

أو:

 say_hi ( new Computer(), "John Doe", "Hello John" );

التي من شأنها أن تنتج You sent a "Hello John" SMS to John Doe You sent a "Hello John" email to John Doe المقابل.

هنا بدأنا بالفعل في اكتشاف بعض ميزات OOP. قدمنا ​​واجهات باستخدام واجهة MessagingCapable .

تعلن الواجهة عن مجموعة من الأساليب التي يجب أن يتم تنفيذها بواسطة الفئة دون تحديد كيفية تنفيذ هذه الأساليب. يجب أن تكون جميع الطرق المعلنة في الواجهة عامة.

لا تدعم PHP الوراثة المتعددة ، مما يعني أنه لا يمكن للفئة أن ترث خصائص / طرق عدة فئات رئيسية.

في حين أنه يمكن أن يمتد فئة واحدة فقط ، إلا أنه يمكنه تنفيذ واجهات متعددة.

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

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

 say_hi( new Computer(), "John", "Hi" );

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

لمحاولة شرح مدى سهولة توسيع المكون الإضافي الخاص بك في البرمجة الشيئية ، دعنا نحاول إضافة المزيد من الوظائف.

إضافة المزيد من الوظائف

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

 interface InternetBrowsingCapable { public function visit_website( $url ); }

سيتم ترميز تنفيذ هذه الواجهة على النحو التالي:

 class Computer implements MessagingCapable, InternetBrowsingCapable { public function send_message( $contact, $message ) { print ('You sent a "' . $message . '" email to ' . $contact ); } public function visit_website( $url ) { print ('You visited "' . $url ); } }

لذلك في فئة الكمبيوتر الحالية ، أضفنا للتو الواجهة الإضافية ليتم تنفيذها ، حيث يمكن للكمبيوتر إرسال رسالة وتصفح الإنترنت وطريقة visit_website( $url ) .

ملاحظة: بالطبع ، نظرًا لأن زيارة عنوان url غير ذي صلة تمامًا say_hi() ، فسنقدم أيضًا وظيفة جديدة ، شيء مثل:

 function visit_url( InternetBrowsingCapable $device, $url ) { $device->visit_website( $url ); }

وهذا كل شيء! بالنسبة إلى أي جهاز يمكنه زيارة عنوان URL ، يمكننا استخدام هذه الوظيفة كما فعلنا مع الكمبيوتر. لا داعي للقلق من تعطل باقي الوظائف. يوضح هذا قابلية التوسع المتاحة عند استخدام OOP مقارنة بالبرمجة الإجرائية.

دعنا نضيف جهاز هاتف ذكي فقط لإظهار بعض الميزات الإضافية. هذا هو الكود بالكامل ، مع إضافة فئة الهاتف الذكي بحيث يمكنك الحصول على صورة أفضل لما يحدث:

 <?php /* * Plugin Name: Communication Plugin */ interface MessagingCapable { public function send_message( $contact, $message ); } interface InternetBrowsingCapable { public function visit_website( $url ); } class Phone implements MessagingCapable { public function send_message( $contact, $message ) { print 'You sent a "' . $message . '" SMS to ' . $contact; } } class Computer implements MessagingCapable, InternetBrowsingCapable { public function send_message( $contact, $message ) { print 'You sent a "' . $message . '" email to ' . $contact; } public function visit_website( $url ) { print 'You visited "' . $url; } } class Smartphone extends Phone implements InternetBrowsingCapable { public function visit_website( $url ) { print 'You visited "' . $url; } public function send_message( $contact, $message ) { parent::send_message( $contact, $message ); print ' from your smartphone'; } } function say_hi( MessagingCapable $device, $contact, $message ) { $device->send_message( $contact, $message ); } function visit_url( InternetBrowsingCapable $device, $url ) { $device->visit_website( $url ); }

تعمل فئة Smartphone على توسيع فئة الهاتف الأصل وتنفيذ واجهة InternetBrowsingCapable . هذا يعني أنه يمكنه إرسال رسالة وزيارة عنوان URL. هنا ، نكتشف ميزة الوراثة. بمعنى آخر ، لدينا تسلسل هرمي للفئات ، وفئة أصل (هاتف) وفئة فرعية (هاتف ذكي).

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

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

 say_hi ( new Phone(), "John Doe", "Hello John" ); say_hi ( new Computer(), "John Doe", "Hello John" ); say_hi ( new Smartphone(), "John Doe", "Hello John" ); visit_url ( new Smartphone(), "https://www.pressidium.com" ); visit_url ( new Computer(), "https://www.pressidium.com" );

للحصول على فهم أفضل للمفهوم بأكمله ، ألق نظرة على مخطط الفصل الخاص بالشفرة أعلاه.

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

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

 class Contact { private $name; private $phone_number; private $email_address; public function __construct( $name, $phone_number, $email_address ) { $this->name = $name; $this->phone_number = $phone_number; $this->email_address = $email_address; } public function get_name() { return $this->name; } public function get_phone_number() { return $this->phone_number; } public function get_email_address() { return $this->email_address; } }

يتم استدعاء طريقة __construct() ، حسب التصميم ، تلقائيًا عند إنشاء كائن. الآن عندما نقوم بإنشاء مثيل لفئة Contact ، يتم استدعاء مُنشئها وتعيين قيم خصائصها الخاصة. ثم نستخدم طرقنا العامة "الحاصل" وهي get_name() و get_phone_number() و get_email_address() لاسترداد هذه القيم.

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

استنتاج

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

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

تم تحسين الأمان أيضًا بسبب التغليف. من ناحية أخرى ، في البرمجة الإجرائية ، تكون جميع البيانات عالمية مما يعني أن الوصول متاح من أي مكان.

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

في المقالات التالية من هذه السلسلة ، سنرى أسلوب البرمجة هذا قيد التنفيذ من خلال تطبيقه على مكون WordPress الإضافي. على وجه التحديد ، سننشئ نسخة من المكون الإضافي Limit Login Attempts الإصدار 1.7.1 الذي أنشأه Johan Eenfeldt ولكن تم تحويله باستخدام نهج Object-Oriented قدر الإمكان.

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

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

انقر هنا لقراءة الجزء 3 في سلسلة البرمجة الشيئية

أنظر أيضا

  • WordPress and Object-Oriented Programming - نظرة عامة