سؤال

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

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

هذا المساء كنت أقرأ عنه روبرت مارتن الصلبة مبادئ:

  • سمبدأ المسؤولية الفردية,
  • يامبدأ القلم/مغلق،
  • لمبدأ استبدال إيسكوف,
  • أنامبدأ فصل الواجهة، و
  • دمبدأ انعكاس التبعية

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

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

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

هل كانت مفيدة؟

المحلول

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

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

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

الجدول الزمني لخلل في برنامج C# كان لدينا:

  1. اقرأ تقارير الأخطاء الغريبة وتتبع المشكلة إلى خطأ بسيط في مكتبة CLR.
  2. استثمر الأيام في التوصل إلى حل بديل يتضمن التقاط الاستثناءات في أماكن غريبة والكثير من الاختراقات التي تعرض الكود للخطر كثيرًا
  3. اقضِ أيامًا في استخلاص الحل البديل عندما تقوم Microsoft بإصدار حزمة خدمة

الجدول الزمني لخلل في برنامج Rails كان لدينا:

  1. اقرأ تقارير الأخطاء الغريبة وتتبع المشكلة إلى خطأ بسيط في مكتبة روبي القياسية
  2. اقضِ 15 دقيقة في إجراء تصحيح بسيط لإزالة الأخطاء من مكتبة روبي، ووضع حراس حولها للتعثر إذا تم تشغيلها على الإصدار الخاطئ من روبي.
  3. استمر في الترميز العادي.
  4. ما عليك سوى حذف Monkeypatch لاحقًا عند إصدار الإصدار التالي من Ruby.

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

ملاحظة:المثال التالي هو ترقيع القرود "تقنيًا"، ولكن هل هو ترقيع القرود "أخلاقيًا"؟أنا لا أغير أي سلوك - هذا مجرد إجراء AOP في روبي ...

class SomeClass
  alias original_dostuff dostuff
  def dostuff
    # extra stuff, eg logging, opening a transaction, etc
    original_dostuff
  end
end

نصائح أخرى

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

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

تصحيح القرد ليس روبيًا صريحًا، بل يتم إجراؤه عبر جافا سكريبت أيضًا، مع تأثيرات سلبية (IMO).

رأيي الشخصي هو أن عملية ترقيع القرود يجب أن تتم فقط

أ) أضف وظيفة إلى الإصدار القديم من اللغة المتوفرة في الإصدار الجديد من اللغة التي تحتاجها.

ب) عندما لا يكون هناك مكان "منطقي" آخر لها.

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

موقفي هو، إذا كنت تستطيع تجنب ذلك، فافعل ذلك.

إذا كنت تستطيع تجنب ذلك بطريقة لطيفة، مجد لك.

إذا لم تتمكن من تجنب ذلك، فاحصل على رأي 200 شخص لأنك ربما لم تفكر في الأمر بالقدر الكافي.

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

setTimeout(function(){ 
    foo(args); 
}, 5000 ); 

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

foo.delay( 5000 , args );

والذي كان له تأثير إضافي لكون هذا النوع من الهراء صالحًا:

foo.delay.delay( 500,  [ 500, args ] ); 

وعلى هذا النحو إلى ما لا نهاية.

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

هل لي أن أشير إلى أن foo.delay أعاد أيضًا كائنًا بطرقه الخاصة، لذا يمكنك القيام بذلك

x = foo.delay( 500, args ); 
x.clear(); 

وحتى

 x.clear.delay(10); 

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

 clearTimeout(x); 

صعب جدا!

(تنصل:لقد مر وقت طويل منذ أن استخدمت moo، وحاولت نسيانه، وقد تكون أسماء الوظائف/البنية غير صحيحة.هذا ليس مرجع API.يرجى التحقق من موقعهم للحصول على التفاصيل (عذرًا، مرجع واجهة برمجة التطبيقات الخاص بهم سيء!))

Mokeypatching خطأ بشكل عام.قم بإنشاء فئة فرعية مناسبة وأضف الطرق.

لقد استخدمت Monkeypatching مرة واحدة في كود الإنتاج.

تكمن المشكلة في أن REST يستخدم GET وPOST وPUT وDELETE.لكن عميل اختبار Django يقدم فقط GET وPOST.لقد قمت بتصحيح أساليب PUT (مثل POST) وDELETE (مثل GET).

نظرًا للارتباط الوثيق بين عميل Django وبرنامج تشغيل اختبار Django، فقد بدا من الأسهل تصحيحه لدعم اختبار REST الكامل.

قد تجد المنير هذه المناقشة حول فئات روبي المفتوحة ومبدأ الفتح المغلق.

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

في نظري، يعتبر تصحيح القرود أحد أشكال AOP.المقالة مبادئ التصميم الموجه نحو الجانب:دروس من التصميم الموجه للكائنات (PDF) يقدم بعض الأفكار حول كيفية تطبيق مبادئ SOLID ومبادئ OOP الأخرى على AOP.

فكرتي الأولى هي أن تصحيح القرود ينتهك OCP، نظرًا لأن عملاء الفصل يجب أن يكونوا قادرين على توقع أن يعمل هذا الفصل بشكل متسق.

الترقيع القرد هو مجرد أمر عادي خطأ, ، IMHO.لم أصادف المبدأ المفتوح/المغلق الذي ذكرته من قبل، لكنه مبدأ أتمسك به منذ فترة طويلة، وأنا أتفق معه بنسبة 100٪.أعتقد أن عملية ترقيع القرود هي بمثابة رائحة رمزية على نطاق أوسع، أو رائحة فلسفة تشفير، إذا جاز التعبير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top