ما هي التأثيرات الجانبيَّة للبرمجة؟


جميل بيلوني

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

تطرَّقت سابقًا باختصار إلى فكرة التأثيرات الجانبية في البرمجة ولكنَّني توسَّعت فيها عندما تحدثت عن استخدام معايير PSR والتي يجب أن يفهمها من يهتم بأخذ فكرة عامة عن بعض نواحي البرمجة. أذكِّرك بتعريف التأثيرات الجانبية كما ذكر في معيار PSR-1 وهو:

يجب على الملف أن ينشئ بنى برمجية جديدة مثل الأصناف والدوال والثوابت ...إلخ. ودون أن يسبب أي "تأثير جانبي"، أو يجب أن ينفِّذ الخطوات المنطقيَّة التي تؤدي إلى "تأثيرات جانبية" ولكن لا يسمح أن ينفِّذ كلا الأمرين.

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

التحدث عن التأثيرات الجانبية في أحد السياقات قد لا يختلف عن سياقات أخرى بينما في البرمجة قد يعني شيئًا آخر.

التأثيرات الجانبيَّة للبرمجة

فكرة «التأثيرات الجانبية» عمومًا أو التعريف العام لها بسيط جدًا وهو:

تأثير اعتيادي أو ثانوي غير مرغوب به لدواء أو علاج طبي.

إن أغفلت جانب العلاج بأكمله فسيبقى لديك التأثيرات الثانوية غير المرغوب بها وهنا يكمن الجزء الذي يحتمل أن يكون مربكًا وهو:

  • نختار أن نضمِّن ملفًا؛
  • نعلم ما يفعله هذا الملف؛
  • وبذلك، إن كنا نعلم ما الذي أدرجناه وما الذي يفعله فكيف يستطيع أن يضيف شيئًا غير مرغوب فيه؟

هكذا أُسأل غالبًا عندما تميل دفة الحديث تجاه موضوع التأثيرات الجانبيَّة. لقد عمَّمتُ مفهوم التأثيرات الجانبيَّة دومًا في البرمجة على أنّه «أي شيء» يغير حالة البرنامج.

التأثيرات الجانبيَّة في ووردبريس

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

يمكن أن يكون ذلك الصنف (class) بسيطًا إذ يتلخص عمله باستدعاء جزء من الواجهة البرمجية لورردبريس (WordPress API)؛ وستُنفَّذ إحدى الدوال عند وقوع حدث معيّن مرتبط بخطَّاف (hook) ثمَّ ستُضاف بعدئذٍ القائمة الفرعية.

لكن ماذا لو أدى ذلك الصنف أو دالة فيه أو تضمين ملف ما إلى إضافة بعض شيفرات JavaScript أو دالة تؤدي إلى تغيير حالة القائمة الفرعية مثل أن تسلك السلوك نفسه الذي تبديه عندما يُضغط عليها إذا مرَّر المستخدم الفأرة فوقها أو أي سلوكٍ آخر لم يقصده المستخدم ولا البرنامج.

يمكننا أن ندعو ما سبق بالتأثير الجانبي الذي يغير من حالة البرنامج.

ما الذي يجب أن تفعله الوحدة (Module)؟

يجب على الصنف القيام بشيء واحد بحسب مبدأ المسؤولية الواحدة (single responsibility principle) وهو:

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

لكن عندما نضيف أمرًا جديدًا إلى الصنف ليزيد من وظائفه أو نغيّر جزءًا جوهريًا فيه فهذا يمثِّل تأثيرًا جانبيًا.

تذكر أنَّ إضافة مسؤوليات جديدة إلى الصنف ليست أمرًا سيئًا بالمطلق (فالأمر لا يماثل التأثيرات الجانبيَّة التي تحدَّث عنها معيار PSR-1) ولكن من المهم معرفة متى يجوز ذلك ومتى يكون من المستحسن تجنبه.

كيف نضيف وظيفةً أخرى للبرنامج؟

أعتقد أنَّ السؤال الذي يجب أن نسأله أنفسنا هو كيف نضيف وظيفة تغير من حالة برنامج وإن أضفناها فهل هي خطأ يا ترى؟

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

لكن التأثيرات الجانبيَّة تظهر عند حدوث إحدى حالات البرنامج.

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

طريقة إضافة وظيفة تعمل بالطريقة نفسها وهي: تعريف أصناف تكون مسؤولة عن أداء غرض محدَّد ثم ترك تلك الأصناف لتنفِّذ ما هي مسؤولةٌ عنه.

عندما تعمل هذه المكونات جنبًا إلى جنب مع مكون آخر يصبح لديك برنامجًا يعمل بشكل صحيح تكون كل وحدة فيه (صنف أو دالة أو غيرهما) تعمل ضمن المسار المحدَّد لها.

الخلاصة

أنا متأكد أنَّ أغلب من يقرأ هذه المقالة قد تبنَّى لنفسه تعريفًا لماهية التأثيرات الجانبيَّة، وأنا فعلت ذلك أيضًا. فكر في ماهية التأثيرات الجانبيَّة من هذه الناحية وهي:

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

إذًا هكذا تتأكد أنَّ الدالة أو الصنف أو الوحدة لا تحوي تأثيرات جانبيَّة.

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

 

ترجمة -وبتصرف- للمقال What Are Programming Side Effects, Anyway?‎‎ لصاحبه Tom McFarlin.

حقوق الصورة البارزة محفوظة لـ Freepik





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


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



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

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

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


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

تسجيل الدخول

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


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