बंदर-पैचिंग बनाम। ठोस। सिद्धांतों?

मैं धीरे-धीरे कुछ निजी परियोजनाओं पर PHP5 से पायथन तक जा रहा हूं, और मैं वर्तमान में अनुभव से प्यार कर रहा हूं। पाइथन मार्ग पर जाने से पहले मैंने रूबी को देखा। रूबी समुदाय से मैंने जो नोटिस किया था वह यह था कि बंदर-पैचिंग आम और अत्यधिक सम्मानित थी। मैं डीबगिंग रूबी एस/डब्ल्यू के परीक्षणों के बारे में डरावनी कहानियों के बहुत पर भी आया क्योंकि किसी ने नौकरी करने के लिए अपेक्षाकृत हानिरहित लाइब्रेरी शामिल की थी, लेकिन किसी को बताए बिना कुछ भारी इस्तेमाल किए गए मूल वस्तु को पैच किया।

मैंने पाइथन को (अन्य कारणों से) इसके क्लीनर सिंटैक्स के लिए चुना और तथ्य यह है कि यह सब कुछ रूबी कर सकता है। पाइथन ओओ को PHP से कहीं ज्यादा बेहतर बना रहा है, और मैं इस बेहतर समझ को बढ़ाने के लिए ओओ सिद्धांतों पर अधिक से अधिक पढ़ रहा हूं।

इस शाम को मैं रॉबर्ट मार्टिन के सॉलिड सिद्धांतों के बारे में पढ़ रहा हूं:

  • Single responsibility principle,
  • Open/closed principle,
  • Liskov substitution principle,
  • Interface segregation principle, and
  • Dependency inversion principle

मैं वर्तमान में तक हूं: सॉफ़्टवेयर एंटीटीज़ (क्लासेस, मॉड्यूल, फ़ंक्शन, ईटीसी) को विस्तार के लिए खोलना चाहिए, लेकिन संशोधन के लिए बंद कर दिया जाना चाहिए

My head's in a spin over the conflict between ensuring consistency in OO design and the whole monkey-patching thing. I understand that its possible to do monkey-patching in Python. I also understand that being "pythonic" is to follow common, well-tested, oop best-practices & principles.

What I'd like to know is the community's opinion on the two opposing subjects; how they interoperate, when its best to use one over the other, whether the monkey-patching should be done at all... hopefully you can provide a resolution to the matter for me.

0
क्या कोई रॉबर्ट सी मार्टिन को सॉलिड सिद्धांतों को श्रेय देने के लिए इस प्रश्न को संपादित कर सकता है?
जोड़ा लेखक quamrana, स्रोत

8 उत्तर

बंदर-पैचिंग (पूर्व-मौजूदा विधियों को ओवरराइट करना या संशोधित करना) और नए तरीकों के सरल जोड़ के बीच एक अंतर है। मुझे लगता है कि उत्तरार्द्ध पूरी तरह से ठीक है, और पूर्व को संदिग्ध रूप से देखा जाना चाहिए, लेकिन मैं अभी भी इसे रखने के पक्ष में हूं।

मुझे उन समस्याओं में से कुछ का सामना करना पड़ा है जहां एक तृतीय पक्ष एक्सटेंशन मुख्य पुस्तकालयों को बंद कर देता है और चीज़ों को तोड़ देता है, और वे वास्तव में चूसते हैं। दुर्भाग्यवश, वे सभी वास्तव में तीसरे पक्ष के विस्तार डेवलपर्स से स्टेम लगते हैं, जो वास्तव में अपने समाधानों को सही तरीके से कैसे विकसित करते हैं, इस बारे में सोचने के बजाय कम से कम प्रतिरोध का मार्ग लेते हैं।
यह बेकार है, लेकिन यह बंदर निर्माताओं की गलती की तुलना में बंदर पैचिंग की गलती नहीं है कि लोग कभी-कभी खुद को काटते हैं।

बंदर पैचिंग के लिए मैंने कभी भी वैध आवश्यकता को देखा है, तीसरी पार्टी या कोर पुस्तकालयों में बग के आसपास काम करना है। इसके लिए, यह अमूल्य है, और अगर मैं इसे करने की क्षमता हटा देता हूं तो मैं वास्तव में निराश होगा।

हमारे पास एक सी # कार्यक्रम में एक बग की समयरेखा थी:

  1. सीएलआर लाइब्रेरी में एक मामूली बग रिपोर्ट में अजीब बग रिपोर्ट पढ़ें और समस्या का पता लगाएं।
  2. अजीब जगहों पर अपवादों को पकड़ने और कोड के साथ समझौता करने वाले बहुत सारे हैक सहित एक कार्यवाही के साथ आने वाले निवेश दिन
  3. माइक्रोसॉफ्ट एक सर्विस पैक जारी करते समय हैकी वर्कअराउंड निकालने के दिन बिताएं

हमारे पास एक रेल कार्यक्रम में एक बग की समयरेखा थी:

  1. एक रूबी मानक लाइब्रेरी में एक मामूली बग में अजीब बग रिपोर्ट पढ़ें और समस्या का पता लगाएं
  2. रूबी लाइब्रेरी से बग को हटाने के लिए मामूली बंदर-पैच प्रदर्शन करने में 15 मिनट व्यतीत करें, और यदि यह रूबी के गलत संस्करण पर चलती है तो यात्रा के लिए गार्ड रख दें।
  3. सामान्य कोडिंग के साथ चलें।
  4. रूबी के अगले संस्करण को रिलीज़ होने पर बस बाद में बंदरगाह हटाएं।

बगफिक्सिंग प्रक्रिया समान दिखती है, मंजीकीचिंग के अलावा, यह 15 मिनट का समाधान है, और 5-सेकेंड 'निष्कर्षण' है, जबकि इसके बिना दर्द और पीड़ा आती है।

पीएस: निम्नलिखित उदाहरण "तकनीकी रूप से" बंदरगाह है, लेकिन क्या यह "नैतिक रूप से" बंदरगाह है? मैं किसी भी व्यवहार को नहीं बदल रहा हूं - यह रूबी में एओपी कर रहा है ...

class SomeClass
  alias original_dostuff dostuff
  def dostuff
    # extra stuff, eg logging, opening a transaction, etc
    original_dostuff
  end
end
0
जोड़ा
मुझे लगता है कि यह आपकी पोस्ट को अच्छी तरह से बताता है: "महान शक्ति के साथ बड़ी ज़िम्मेदारी आती है।" स्पष्ट रूप से, मुझे बंदरगाह से प्यार है, लेकिन मैं मौजूदा तरीकों को ओवरराइड करने से बचने के लिए प्रवृत्त हूं (हालांकि मैं इसे मानता हूं कि यह वास्तव में सबसे अच्छा विकल्प है), ठीक उसी कारण से आप स्पष्ट करते हैं।
जोड़ा लेखक Mike Stone, स्रोत
बंदर पैचिंग के लिए निश्चित रूप से एक समय और स्थान है, लेकिन मैं सहमत हूं कि यह दुर्व्यवहार कर सकता है और उसका दुरुपयोग किया जाएगा। बंदर पैचिंग का एक और प्रकार एंटीवायरस उत्पाद और मैलवेयर रूटकिट है - वे कर्नेल में चारों ओर सामान ले जाते हैं - जो सभी प्रकार के चोटों का कारण बनता है।
जोड़ा लेखक Bryan Rehbein, स्रोत

मेरे विचार में, बंदर पकड़ने के लिए उपयोगी है लेकिन कुछ ऐसा है जिसका दुरुपयोग किया जा सकता है। लोग इसे खोजते हैं और महसूस करते हैं कि इसे हर परिस्थिति में इस्तेमाल किया जाना चाहिए, जहां शायद एक मिश्रण या अन्य निर्माण अधिक उपयुक्त हो सकता है।

मुझे नहीं लगता कि यह ऐसा कुछ है जिसे आपको बहिष्कृत करना चाहिए, यह सिर्फ कुछ ऐसा है जो रूबी लोग उपयोग करना पसंद करते हैं। आप पाइथन के साथ समान चीजें कर सकते हैं लेकिन समुदाय ने इस दृष्टिकोण को लिया है कि चीजें सरल और अधिक स्पष्ट होनी चाहिए।

0
जोड़ा

मोकेपेचिंग आम तौर पर गलत है। एक उचित उपclass बनाएँ और विधियों को जोड़ें।

मैंने उत्पादन कोड में एक बार बंदरगाह का उपयोग किया है।

मुद्दा यह है कि आरईएसटी जीईटी, पोस्ट, पुट और डिलीट का उपयोग करता है। लेकिन Django परीक्षण क्लाइंट केवल जीईटी और पोस्ट प्रदान करता है। मैंने PUT (POST की तरह) के लिए monkeypatched विधियों और DELETE (जीईटी की तरह) है।

Django क्लाइंट और Django परीक्षण ड्राइवर के बीच तंग बाध्यकारी के कारण, यह पूर्ण आरईएसटी परीक्षण का समर्थन करने के लिए बंदरपैच करने के लिए सबसे आसान लग रहा था।

0
जोड़ा

आपको प्रबुद्ध यह चर्चा

हालांकि मुझे रूबी पसंद है, मुझे लगता है कि बंदर-पैचिंग चीजों को पूरा करने के लिए अंतिम उपाय का एक साधन है। सभी चीजें बराबर होती हैं, मैं पारंपरिक ओओ तकनीकों का उपयोग करनात्मक प्रोग्रामिंग भलाई के छिड़काव के साथ करना पसंद करता हूं।

0
जोड़ा

बंदर पैचिंग रूबी-स्पष्ट नहीं है, यह नकारात्मक (आईएमओ) प्रभावों के साथ, पूरे जावास्क्रिप्ट पर भी किया जाता है।

मेरी व्यक्तिगत राय है बंदर पैचिंग केवल किया जाना चाहिए

ए) किसी भाषा के पुराने संस्करण में कार्यक्षमता जोड़ें जो आपको आवश्यक भाषा के नए संस्करण में उपलब्ध है।

बी) जब इसके लिए कोई अन्य "तार्किक" जगह नहीं है।

बंदर पैचिंग वास्तव में भयानक बनाने के कई आसान तरीके हैं, जैसे कि अतिरिक्त कार्य जैसे बुनियादी कार्यों को बदलने की क्षमता।

मेरा रुख है, अगर आप इससे बच सकते हैं, तो ऐसा करें।

यदि आप इसे एक अच्छे तरीके से टाल सकते हैं, तो आप के लिए।

यदि आप इससे बच नहीं सकते हैं, तो 200 लोगों की राय प्राप्त करें क्योंकि आपने शायद इसके बारे में सोचा नहीं है।

My pet hate is mootools extending the function object. Yes, you can do this. Instead of people just learning how JavaScript works:

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

प्रत्येक फ़ंक्शन ऑब्जेक्ट में एक नई विधि शामिल की गई थी, (हाँ, मैं मजाक नहीं कर रहा हूं) ताकि कार्यों के पास अब अपना कार्य हो।

foo.delay( 5000 , args );

इस तरह के बकवास का अतिरिक्त प्रभाव वैध था:

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

और उस विज्ञापन infinitum की तरह।

परिणाम? अब आपके पास लाइब्रेरी नहीं है, और एक भाषा है, आपका लैंगेज लाइब्रेरी में धनुष करता है और यदि लाइब्रेरी गुंजाइश में होती है, तो आपके पास अब कोई भाषा नहीं होती है, और आप केवल वही काम नहीं कर सकते जब वे सीखते हैं भाषा, और इसके बजाय आदेशों का एक नया सबसेट सीखना है, ताकि यह उसके चेहरे पर फ्लैट न हो (अत्यधिक मंदी की कीमत पर!)

may i note that foo.delay also returned an object, with its own methods, so you could do

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

और भी

 x.clear.delay(10); 

जो अत्यधिक उपयोगी लग सकता है, ... लेकिन आपको इस व्यवहार्य बनाने के लिए उपयोग किए जाने वाले विशाल ओवरहेड को ध्यान में रखना होगा।

 clearTimeout(x); 

बहुत कठिन!

(Disclaimer: its been a while since I used moo, and have tried to forget it, and function names/structure may be incorrect. This is not an API reference. Please check their site for details ( sorry, their API reference sucks! ))

0
जोड़ा
वाकई, मैं असहमत हूं। जहां यह तर्कसंगत रूप से संबंधित है वहां कार्यक्षमता जोड़ने की क्षमता मुझे बहुत समझ में आता है। foo.delay (5000, तर्क); एक नियमित सेटटाइमआउट की तुलना में मेरे लिए काफी अधिक पठनीय है। यह बिल्कुल बंदरगाह की तरह है जो खराब बंदरगाह की तरह अनजान और आश्चर्यजनक के बजाय कोड को और अधिक पढ़ाता है। यह शक्तिशाली है, और दुरुपयोग के लिए संभव है, लेकिन यह कोड को और अधिक समझने में भी मदद कर सकता है। रिकॉर्ड के लिए, मैं mootools का उपयोग नहीं करता, लेकिन यह monkeypatching का एक अच्छा उपयोग है।
जोड़ा लेखक Mike Stone, स्रोत

मेरा पहला विचार यह है कि बंदर-पैचिंग ओसीपी का उल्लंघन करता है, क्योंकि कक्षा के ग्राहक उस कक्षा को लगातार काम करने की उम्मीद कर सकते हैं।

0
जोड़ा

मेरी आंखों में, बंदर-पैचिंग एओपी का एक रूप है। आलेख पहलू-ओरिएंटेड डिज़ाइन सिद्धांत: ऑब्जेक्ट-ओरिएंटेड डिज़ाइन से सबक (पीडीएफ) कुछ विचार देता है कि कैसे AOL पर सोलिड और अन्य ओओपी सिद्धांत लागू किए जा सकते हैं।

0
जोड़ा

बंदर-पैचिंग सिर्फ सादा गलत , IMHO है। मैं आपके द्वारा पहले उल्लेख किए गए खुले/बंद सिद्धांत में नहीं आया हूं, लेकिन यह एक सिद्धांत है जिसे मैंने स्वयं तक रखा है, मैं इसके साथ 100% सहमत हूं। मैं एक बड़े पैमाने पर एक कोड-गंध के रूप में बंदर-पैचिंग के बारे में सोचता हूं, एक कोडिंग-दर्शन-गंध, जैसा कि यह था।

0
जोड़ा
निश्चित रूप से एक दर्शन गंध, अच्छी तरह से डाल दिया।
जोड़ा लेखक JoeBloggs, स्रोत