क्या रिफ्लेक्शन का उपयोग करने में समस्याएं हैं?


49

मुझे पता नहीं क्यों, लेकिन मुझे हमेशा लगता है कि जब मैं प्रतिबिंब का उपयोग करता हूं तो मैं "धोखा" देता हूं - शायद यह प्रदर्शन के हिट होने के कारण मुझे पता है कि मैं ले रहा हूं।

मेरा एक हिस्सा कहता है, अगर यह उस भाषा का हिस्सा है जिसका आप उपयोग कर रहे हैं और यह पूरा कर सकती है कि आप क्या करने की कोशिश कर रहे हैं, तो इसका उपयोग क्यों न करें। मेरे दूसरे भाग का कहना है, वहाँ एक तरीका है कि मैं प्रतिबिंब का उपयोग किए बिना ऐसा कर सकता हूं। मुझे लगता है कि शायद यह स्थिति पर निर्भर करता है।

प्रतिबिंब का उपयोग करते समय मुझे किन संभावित मुद्दों पर ध्यान देने की आवश्यकता है और मुझे उनके बारे में कितना चिंतित होना चाहिए? अधिक पारंपरिक समाधान खोजने की कोशिश करने में कितना खर्च होता है?


2
मुझे लगता है कि यह भाषा और पर्यावरण पर निर्भर करता है। कुछ इसका समर्थन करते हैं, यहां तक ​​कि इसे प्रोत्साहित भी करते हैं। कभी-कभी जावा में काम करते समय मैंने बेहतर प्रतिबिंब समर्थन की कामना की है।
FrustratedWithFormsDesigner

18
ठीक है, मुझे लगता है कि "धोखा देने वाले प्रतिबिंब" और उसके वैध उपयोग के बीच इसे अलग करना कठिन नहीं है: जब आप निजी सदस्यों का निरीक्षण करते हैं या निजी तरीकों को कॉल करने के लिए इसका उपयोग करते हैं (इंटरफेस के आसपास काम करने के लिए), तो यह बहुत संभावना है कि धोखा हो। जब आप इसका उपयोग उन प्रकारों के साथ बातचीत करने के लिए करते हैं जिनके बारे में आपको कोई जानकारी नहीं है, तो यह शायद ठीक है (डेटाबाइंडिंग, प्रॉक्सीज़ आदि)।
फाल्कन

1
आप किस भाषा का उपयोग कर रहे हैं? ब्रेनफैक में प्रतिबिंब नहीं है और अजगर सिर्फ अलग है।
जॉब

1
मैंने यह भी कभी नहीं समझा कि प्रतिबिंब के माध्यम से निजी तरीकों तक पहुंचने की अनुमति क्यों है। मेरे अंतर्ज्ञान के अनुसार इसे मना किया जाना चाहिए।
जियोर्जियो

3
इस बात पर यकीन करना मुश्किल है कि बिना किसी संपादन के इस तरह के खराब शब्दों वाले प्रश्न को 27 अपवोट मिले।
आरोन

जवाबों:


48

नहीं, यह धोखा नहीं है - यह कुछ प्रोग्रामिंग भाषाओं में समस्याओं को हल करने का एक तरीका है।

अब, यह अक्सर सबसे अच्छा (सबसे स्वच्छ, सरलतम, बनाए रखने में आसान) समाधान नहीं है। यदि कोई बेहतर तरीका है, तो उस एक का उपयोग करें। हालाँकि, कभी-कभी ऐसा नहीं होता है। या अगर वहाँ है, तो यह सिर्फ इतना अधिक जटिल है, जिसमें बहुत सारे कोड डुप्लीकेशन आदि शामिल हैं, जो इसे असरदार बनाता है (लंबे समय तक बनाए रखना मुश्किल है)।

हमारे वर्तमान परियोजना (जावा) से दो उदाहरण:

  • हमारे कुछ परीक्षण उपकरण XML फ़ाइलों से कॉन्फ़िगरेशन लोड करने के लिए प्रतिबिंब का उपयोग करते हैं। आरंभिक किए जाने वाले वर्ग में विशिष्ट क्षेत्र होते हैं, और कॉन्फ़िगर लोडर प्रतिबिंब का उपयोग fieldXवर्ग में उपयुक्त क्षेत्र में नामित एक्सएमएल तत्व से मेल खाने के लिए करता है , और बाद वाले को आरंभ करने के लिए। कुछ मामलों में, यह मक्खी पर पहचाने गए गुणों में से एक साधारण जीयूआई संवाद बॉक्स का निर्माण कर सकता है। प्रतिबिंब के बिना, यह कई अनुप्रयोगों में कोड की सैकड़ों लाइनें ले जाएगा। तो परावर्तन ने हमें बहुत ही उपद्रव के बिना एक सरल उपकरण को जल्दी से एक साथ लाने में मदद की, और हमें अप्रासंगिक के बजाय महत्वपूर्ण भाग (हमारे वेब ऐप का पुन: परीक्षण, सर्वर लॉग आदि का विश्लेषण करने) पर ध्यान केंद्रित करने में सक्षम बनाया।
  • हमारी विरासत वेब ऐप का एक मॉड्यूल DB टेबल से एक्सेल शीट और बैक में डेटा निर्यात / आयात करना था। इसमें बहुत सारे डुप्लिकेट किए गए कोड थे, जहां निश्चित रूप से डुप्लिकेट समान नहीं थे, उनमें से कुछ में कीड़े आदि थे। प्रतिबिंब, आत्मनिरीक्षण और एनोटेशन का उपयोग करते हुए, मैं अधिकांश दोहराव को खत्म करने में कामयाब रहा, कोड की मात्रा को खत्म कर दिया। 5K से 2.4K नीचे, कोड को अधिक मजबूत बनाने और बनाए रखने या विस्तारित करने के लिए आसान तरीका। अब वह मॉड्यूल हमारे लिए एक समस्या बन गया है - प्रतिबिंब के विवेकपूर्ण उपयोग के लिए धन्यवाद।

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


8
+1 रूपांतरण डेटा आयात / निर्यात के लिए अविश्वसनीय रूप से उपयोगी है जब आपके पास रूपांतरण कारणों के लिए मध्यवर्ती ऑब्जेक्ट होते हैं।
एड जेम्स

2
यह डेटा-चालित ऐप्स में भी अविश्वसनीय रूप से उपयोगी है - बड़े पैमाने पर स्टैक का उपयोग करने के बजाय if (propName = n) setN(propValue);, आप अपने (यानी) XML टैग को अपने कोड गुणों के समान नाम दे सकते हैं और उन पर एक लूप चला सकते हैं। यह विधि बाद में गुणों को जोड़ने के लिए बहुत आसान बना देती है।
माइकल के

परावर्तन का उपयोग धाराप्रवाह इंटरफ़ेन्स में बहुत अधिक किया जाता है, जैसे फ़्लुएंनहाइबरनेट।
स्कॉट व्हिटलॉक

4
@ मिचेल: जब तक आप वर्ग में उन गुणों में से एक का नाम बदलने का निर्णय लेते हैं और पाते हैं कि आपका कोड फट गया है। यदि आपको उन चीज़ों के साथ तुलनात्मकता बनाए रखने की आवश्यकता नहीं है जो आपके कार्यक्रम को उत्पन्न करती हैं, तो यह ठीक है, लेकिन मुझे संदेह है कि यह हम में से अधिकांश नहीं है।
बिली ओनेल

1
@ बिली, मेरा मतलब यह नहीं है कि मैं आपके विरोध में हूं, आपने जो लिखा है, मैं उससे सहमत हूं। हालाँकि, आपके द्वारा लाया जाने वाला उदाहरण IMHO सामान्य नियम का एक उप भाग है, "सार्वजनिक इंटरफेस को बदलने से बचें"।
पेटर टॉर्क

37

यह धोखा नहीं है। लेकिन यह आमतौर पर कम से कम निम्नलिखित कारणों के लिए उत्पादन कोड में एक बुरा विचार है:

  • आप संकलन-समय प्रकार की सुरक्षा खो देते हैं - यह संकलक को सत्यापित करने में सहायक होता है कि संकलन विधि समय पर उपलब्ध है। यदि आप परावर्तन का उपयोग कर रहे हैं, तो आपको रनटाइम पर एक त्रुटि मिलेगी जो अंत उपयोगकर्ताओं को प्रभावित कर सकती है यदि आप अच्छी तरह से परीक्षण नहीं करते हैं। यहां तक ​​कि अगर आप त्रुटि को पकड़ते हैं, तो भी डिबग करना अधिक कठिन होगा।
  • यह रिफैक्टिंग करते समय कीड़े का कारण बनता है - यदि आप इसके नाम के आधार पर किसी सदस्य तक पहुंच रहे हैं (जैसे कि हार्ड-कोडेड स्ट्रिंग का उपयोग कर रहे हैं) तो यह अधिकांश कोड रिफैक्टिंग टूल द्वारा नहीं बदलेगा और आपके पास तुरंत एक बग होगा, जो काफी हो सकता है नीचे ट्रैक करने के लिए मुश्किल है।
  • प्रदर्शन धीमा है - रनटाइम पर प्रतिबिंब सांख्यिकीय रूप से संकलित विधि कॉल / चर लुकअप की तुलना में धीमा होने वाला है। यदि आप कभी-कभार केवल प्रतिबिंब बना रहे हैं, तो इससे कोई फर्क नहीं पड़ेगा, लेकिन यह उन मामलों में एक प्रदर्शन अड़चन बन सकता है, जहां आप प्रति सेकंड हजारों या लाखों बार प्रतिबिंब के माध्यम से कॉल कर रहे हैं। मैंने एक बार कुछ क्लोजर कोड में 10x स्पीडअप प्राप्त किया, ताकि सभी प्रतिबिंब समाप्त हो सकें, हां, यह एक वास्तविक मुद्दा है।

मैं निम्नलिखित मामलों में प्रतिबिंब के उपयोग को सीमित करने का सुझाव दूंगा:

  • के लिए त्वरित प्रोटोटाइप या "throwaway" कोड जब यह सरल समाधान है
  • के लिए वास्तविक प्रतिबिंब उपयोग के मामलों , जैसे आईडीई टूलींग है कि एक उपयोगकर्ता क्षेत्रों / रनटाइम पर एक मनमाना वस्तु के तरीकों की जांच करने की अनुमति देता है।

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


3
+1 - प्रतिबिंब के लिए कई उपयोग के मामले हैं; लेकिन अधिकांश समय मैं प्रोग्रामरों को इसका उपयोग करते हुए देख रहा हूं कि वे गंभीर खामियों के साथ डिजाइनों पर पैपिंग कर रहे हैं। इंटरफेस को परिभाषित करें और प्रतिबिंब पर निर्भरता को हटाने का प्रयास करें। GOTO की तरह, इसके उपयोग हैं, लेकिन उनमें से ज्यादातर अच्छे नहीं हैं। (उनमें से कुछ अच्छे हैं, निश्चित रूप से)
बिली ओनेल

3
ध्यान रखें कि उपरोक्त बिंदु आपकी पसंदीदा भाषा पर लागू हो भी सकते हैं और नहीं भी। उदाहरण के लिए, प्रतिबिंब का स्मालटाक में कोई गति दंड नहीं है, न ही आप संकलन-समय की सुरक्षा खोते हैं, क्योंकि गणना पूरी तरह से देर से होती है।
फ्रैंक शीयर

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

2
@ डेडलिनक्स: आप किस नकारात्मक पहलू का उल्लेख करते हैं? इस उत्तर में कई हैं। प्रदर्शन का मुद्दा केवल एक चीज है जो भाषा पर निर्भर है।
बिली ओले

1
मुझे यह जोड़ना चाहिए कि रिफैक्टिंग के दौरान होने वाली दूसरी समस्या - शायद सबसे गंभीर है। विशेष रूप से, किसी चीज का नाम विशेष पर भरोसा करने पर उस चीज का नाम बदल जाने पर तुरंत टूट जाता है। इस प्रकार हुई त्रुटियां सूचनात्मक से कम हो सकती हैं, जब तक कि आप बहुत सावधान न हों।
फ्रैंक शीयर

11

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


2
+1, यह मुझे समझने में मदद करता है कि प्रतिबिंब क्या है । मैं एक C ++ प्रोग्रामर हूं, और इसलिए मैंने कभी भी प्रतिबिंब नहीं बनाया है। इससे मदद मिलती है। (हालांकि मैं स्वीकार करता हूं कि मेरे दृष्टिकोण से, परावर्तन भाषा में कमी को समेटने की कोशिश की तरह लगता है। हम C ++ लोग उसी के लिए टेम्पलेट का उपयोग करते हैं। इसलिए मुझे लगता है कि आप भी ऐसा ही कह सकते हैं। :)
ग्रेफेड

4
पुन: प्रदर्शन - कुछ मामलों में, आप पूरी तरह से प्रदर्शन कोड वापस लिखने के लिए प्रतिबिंब एपीआई का उपयोग कर सकते हैं। उदाहरण के लिए, .NET में आप आईएल को वर्तमान ऐप में लिख सकते हैं - इसलिए आपका "प्रतिबिंब" कोड किसी भी अन्य कोड के समान ही तेज हो सकता है (सिवाय इसके कि आप बहुत अधिक / और / जो कुछ भी निकाल सकते हैं, जैसा कि आप पहले ही कर चुके हैं) पता लगा सटीक नियम)
मार्क Gravell

@ ग्रेफेड: एक अर्थ में, टेम्प्लेट्स कंपाइल-टाइम-ओनली रिफ्लेक्शन कर रहे हैं। रनटाइम में इसे करने में सक्षम होने के कारण आवेदन में शक्तिशाली क्षमताओं को फिर से स्थापित किए बिना निर्माण करने की अनुमति देने का लाभ है। आप लचीलेपन के लिए प्रदर्शन का व्यापार करते हैं, एक स्वीकार्य ट्रेडऑफ़ जितना आप उम्मीद कर सकते हैं (अपने सी ++ बैकग्राउंड को देखते हुए)।
डोनाल्ड फेलो

मैं आपका जवाब नहीं समझता। आप कह रहे हैं कि प्रतिबिंब का उपयोग करने वाले प्रोग्राम उन लोगों की तुलना में अधिक बनाए रखने योग्य हैं, जैसे कि प्रतिबिंब एक बेहतर प्रोग्रामिंग मॉडल है जिसे प्रदर्शन की आवश्यकता नहीं होने पर ऑब्जेक्ट-ओरिएंटेड और प्रक्रियात्मक कार्यक्रमों को दबा देना चाहिए।
डेविड एफएस

8

निश्चित रूप से यह सब इस बात पर निर्भर करता है कि आप क्या हासिल करने की कोशिश कर रहे हैं।

उदाहरण के लिए, मैंने एक मीडिया चेकर एप्लिकेशन लिखा है जो यह जांचने के लिए निर्भरता इंजेक्शन का उपयोग करता है कि किस प्रकार की मीडिया (एमपी 3 फाइलें या जेपीईजी फाइलें) की जांच करें। शेल को प्रत्येक प्रकार के लिए प्रासंगिक जानकारी वाले ग्रिड को प्रदर्शित करने की आवश्यकता थी, लेकिन उसे यह पता नहीं था कि यह क्या प्रदर्शित करने जा रहा है। यह विधानसभा में परिभाषित किया गया है जो उस प्रकार के मीडिया को पढ़ता है।

इसलिए मुझे प्रदर्शित करने के लिए स्तंभों की संख्या और उनके प्रकार और नाम प्राप्त करने के लिए प्रतिबिंब का उपयोग करना पड़ा ताकि मैं ग्रिड को सही ढंग से सेट कर सकूं। इसका मतलब यह भी था कि मैं किसी अन्य कोड या कॉन्फ़िगरेशन फ़ाइल को बदले बिना इंजेक्ट लाइब्रेरी को अपडेट कर सकता हूं (या एक नया निर्माण कर सकता हूं)।

केवल एक अन्य तरीका एक कॉन्फ़िगरेशन फ़ाइल होना चाहिए था जिसे अद्यतन करने की आवश्यकता होगी जब मैंने मीडिया के प्रकार की जाँच की। इसने आवेदन के लिए विफलता का एक और बिंदु पेश किया होगा।


1
"निश्चित रूप से यह सब इस बात पर निर्भर करता है कि आप क्या हासिल करने की कोशिश कर रहे हैं।" +1
डेवशॉ

7

यदि आप एक पुस्तकालय लेखक हैं, तो प्रतिबिंब एक भयानक उपकरण है , और इस प्रकार आने वाले डेटा पर कोई प्रभाव नहीं पड़ता है। प्रतिबिंब और मेटा-प्रोग्रामिंग का संयोजन आपके पुस्तकालय को मनमाने ढंग से कॉल करने वालों के साथ काम करने की अनुमति दे सकता है, उनके बिना कोड-पीढ़ी आदि के हुप्स के माध्यम से कूदने के लिए।

मैं हालांकि आवेदन कोड में प्रतिबिंब से हतोत्साहित करने की कोशिश करता हूं ; ऐप लेयर में आपको अलग-अलग रूपकों का उपयोग करना चाहिए - इंटरफेस, एब्स्ट्रैक्शन, इनकैप्सुलेशन आदि।


इस तरह के पुस्तकालयों का उपयोग अक्सर कठिन होता है और सबसे अच्छा बचा जाता है (जैसे वसंत)।
श्रीधर सरनोबत

@ श्रीधर तो आपने कभी भी क्रमबद्ध एपीआई का उपयोग नहीं किया है? या कोई ORM / माइक्रो- ORM?
मार्क Gravell

मैंने उन्हें अपनी पसंद के बिना चुना है। अगर मैं यह नहीं बता पा रहा था कि मैं क्या कर सकता हूं, तो यह उन समस्याओं में चल रहा है जिनसे मैं बच सकता था।
श्रीधर सरनोबत

7

डेवलपर्स के लिए उपकरण बनाने के लिए प्रतिबिंब शानदार है।

चूंकि यह आपके बिल्ड वातावरण को कोड का निरीक्षण करने की अनुमति देता है और संभावित रूप से कोड का निरीक्षण करने / निष्क्रिय करने के लिए सही उपकरण उत्पन्न करता है।

एक सामान्य प्रोग्रामिंग तकनीक के रूप में यह उपयोगी हो सकता है लेकिन ज्यादातर लोगों की कल्पना से अधिक भंगुर है।

प्रतिबिंब (IMO) के लिए वास्तव में एक विकास का उपयोग यह है कि यह एक सामान्य स्ट्रीमिंग लाइब्रेरी को बहुत ही सरल बनाता है (जब तक आपका वर्ग विवरण कभी नहीं बदलता है (तब यह एक बहुत ही भंगुर समाधान बन जाता है)।


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

5

प्रतिबिंब का उपयोग अक्सर ओओ भाषाओं में हानिकारक होता है यदि महान जागरूकता के साथ उपयोग नहीं किया जाता है।

मैंने StackExchange साइटों पर कितने बुरे प्रश्न देखे हैं, इसकी गिनती मैंने खो दी है

  1. उपयोग में आने वाली भाषा OO है
  2. लेखक यह पता लगाना चाहता है कि किस प्रकार की वस्तु को पारित किया गया है और फिर इसके तरीकों में से एक को कॉल करें
  3. लेखक इस बात को मानने से इंकार करता है कि यह गलत तकनीक है और जो भी इसे "मेरी मदद करने के लिए नहीं जानता" के रूप में इंगित करता है, किसी पर भी आरोप लगाता है

यहाँ हैं विशिष्ट उदाहरण।

OO का अधिकांश बिंदु यही है

  1. आप समूह कार्य करते हैं जो जानते हैं कि किसी चीज़ के साथ एक संरचना / अवधारणा को कैसे हेरफेर करना है।
  2. आपके कोड के किसी भी बिंदु में आपको किसी वस्तु के प्रकार के बारे में पर्याप्त जानना चाहिए कि उसके पास क्या प्रासंगिक कार्य हैं और यह उन कार्यों के अपने विशेष संस्करण को कॉल करने के लिए कहें।
  3. आप प्रत्येक फ़ंक्शन के लिए सही इनपुट प्रकार निर्दिष्ट करके और प्रत्येक फ़ंक्शन को पता है कि प्रासंगिक है की तुलना में पिछले बिंदु की सच्चाई को सुनिश्चित करते हैं (और अधिक नहीं)।

यदि आपके कोड के किसी भी बिंदु पर, बिंदु 2 आपके द्वारा पारित की गई वस्तु के लिए मान्य नहीं है, तो इनमें से एक या अधिक सत्य है

  1. गलत इनपुट में फीड किया जा रहा है
  2. आपका कोड खराब संरचित है
  3. तुम्हें पता नहीं है कि तुम क्या कर रहे हो।

गरीब कुशल डेवलपर्स को बस यह नहीं मिलता है और मानते हैं कि उन्हें अपने कोड के किसी भी हिस्से में कुछ भी पारित किया जा सकता है और वे कर सकते हैं जो संभावनाओं के एक (हार्ड-कोडित) सेट से चाहते हैं। ये बेवकूफियां प्रतिबिंब का बहुत उपयोग करती हैं ।

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


3

एक विकल्प, ऐसे मामलों में जहां परिलक्षित कक्षाओं का डोमेन अच्छी तरह से परिभाषित है, रनटाइम पर प्रतिबिंब का उपयोग करने के बजाय, कोड उत्पन्न करने के लिए अन्य मेटाडेटा के साथ प्रतिबिंब का उपयोग करना है। मैं FreeMarker / FMPP का उपयोग करता हूं; चुनने के लिए बहुत सारे अन्य उपकरण हैं। इसका लाभ यह है कि आप "वास्तविक" कोड के साथ समाप्त होते हैं जिसे आसानी से डीबग किया जा सकता है, आदि।

स्थिति के आधार पर, यह आपको बहुत तेज़ कोड बनाने में मदद कर सकता है - या बस बहुत से कोड ब्लोट। यह प्रतिबिंब के नुकसान से बचता है:

  • संकलन-समय प्रकार की सुरक्षा का नुकसान
  • रीफैक्टरिंग के कारण कीड़े
  • धीमी गति से प्रदर्शन

पहले उल्लेख किया जा चुका है।

यदि प्रतिबिंब धोखा देने जैसा महसूस करता है, तो ऐसा इसलिए हो सकता है क्योंकि आप इसे बहुत अधिक अनुमान पर आधारित कर रहे हैं जो आप निश्चित नहीं हैं, और आपका आंत आपको चेतावनी दे रहा है कि यह जोखिम भरा है। अपने स्वयं के मेटाडेटा के साथ प्रतिबिंब में अंतर्निहित मेटाडेटा को बढ़ाने का एक तरीका प्रदान करना सुनिश्चित करें, जहां आप वास्तविक दुनिया की कक्षाओं के सभी quirks और विशेष मामलों का वर्णन कर सकते हैं।


2

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

अच्छा प्रतिबिंब उपयोग का एक उदाहरण सामान्य वेब सेवा इंटरफ़ेस कक्षाएं हैं: पेलोड कार्यक्षमता से प्रोटोकॉल कार्यान्वयन को अलग करने के लिए एक विशिष्ट डिज़ाइन है। तो फिर आपके पास एक वर्ग है (चलो इसे कॉल करें T) जो आपके पेलोड को लागू करता है, और दूसरा जो प्रोटोकॉल को लागू करता है ( P)। Tकाफी सीधा है: आप जो भी कॉल करना चाहते हैं, उसके लिए बस एक तरीका लिखें, जो भी करना चाहिए। Pहालाँकि, कॉल करने के लिए वेब सेवा कॉल को मैप करने की आवश्यकता है। इस मानचित्रण को सामान्य बनाना वांछनीय है, क्योंकि यह अतिरेक से बचा जाता है, और Pअत्यधिक पुन: प्रयोज्य बनाता है। परावर्तन T, रनटाइम पर कक्षा का निरीक्षण करने और Pवेब सेवा प्रोटोकॉल के माध्यम से पारित स्ट्रिंग्स के आधार पर अपने तरीकों को कॉल करने का साधन प्रदान करता है, बिना किसी कक्षा के संकलन-समय के ज्ञान केT। 'कोड के बारे में कोड' नियम का उपयोग करते हुए, कोई यह तर्क दे सकता है कि कक्षा Pमें Tअपने डेटा के भाग के रूप में कोड है ।

हालाँकि।

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

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


2

एक समस्या जो हमारे पास रिफ्लेक्शन के साथ है वह यह है कि जब हमने मिश्रण में ओफ़्फ़्यूशन को जोड़ा । सभी वर्गों को नए नाम मिलते हैं और अचानक अपने नाम से एक वर्ग या कार्य को लोड करना बंद हो जाता है।


1

यह पूरी तरह से निर्भर करता है। किसी चीज़ का एक उदाहरण जो बिना प्रतिबिंब के कठिन होगा, वह ऑब्जेक्टलिस्टव्यू को दोहराने के लिए होगा । यह मक्खी पर IL कोड भी बनाता है।


1

परावर्तन-आधारित प्रणाली बनाने की प्राथमिक विधि परावर्तन है। मुझे यह जानकर आश्चर्य नहीं होगा कि यह अधिकांश एमवीसी रूपरेखा के अंदर उपयोग में है। यह ORM में एक प्रमुख घटक है। संभावना है, आप पहले से ही हर दिन इसके साथ निर्मित घटकों का उपयोग कर रहे हैं।

इस तरह के उपयोग का विकल्प कॉन्फ़िगरेशन है, जिसमें कमियों का अपना सेट है।


0

प्रतिबिंब उन चीजों को प्राप्त कर सकता है जो बस व्यावहारिक रूप से अन्यथा नहीं किया जा सकता है।

उदाहरण के लिए, इस कोड को अनुकूलित करने के तरीके पर विचार करें:

int PoorHash(char Operator, int seed, IEnumerable<int> values) {
    foreach (var v in values) {
        seed += 1;
        switch (char) {
            case '+': seed += v; break;
            case '^': seed ^= v; break;
            case '-': seed -= v; break;
            ...
        }
        seed *= 3;
    }
    return seed;
}

आंतरिक लूप के बीच में एक महंगा परीक्षण स्मैक है, लेकिन इसे निकालने पर प्रत्येक ऑपरेटर के लिए एक बार लूप को फिर से लिखना पड़ता है। परावर्तन हमें लूप को दर्जन बार दोहराए बिना (और इस तरह स्थिरता बनाए रखते हुए) परीक्षण के साथ, सममूल्य पर प्रदर्शन प्राप्त करने की अनुमति देता है। बस उस लूप को जेनरेट करें और संकलित करें जो आपको मक्खी पर चाहिए।

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

(नोट: मैंने शुरू में एक चारक के बजाय फंक में पास होने की कोशिश की थी, और यह थोड़ा बेहतर था, लेकिन लगभग 10x प्रतिबिंब प्राप्त नहीं हुआ।)


1
बेहतर अनुकूलन इसके बजाय एक फ़नकार को पारित करना है। JIT कंपाइलर द्वारा रनटाइम पर इनबिल्ट होने की संभावना होगी और रिफ्लेक्शन की तुलना में यह अधिक टिकाउ होगा।
बिली ओनेल

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

इसके अलावा, मैं इंगित करता हूं कि आपको जो मिला है, वह वास्तव में आत्म संशोधित कोड है, जो वास्तव में प्रतिबिंब नहीं है। सबसे अधिक भाषाओं में प्रतिबिंब एपीआई के माध्यम से इसे एक्सेस किया जाता है, जो प्रतिबिंब का समर्थन करते हैं, लेकिन यह सिर्फ उन्हीं भाषाओं में किया जा सकता है जो प्रतिबिंब का समर्थन नहीं करते हैं (जैसे कि यह C ++ में संभव होगा)
बिली ओनेल

मैं मानक 'संरचनात्मक समानता' उदाहरण से बचना चाहता था। आत्म-संशोधन कोड के लिए प्रतिबिंब आवश्यक नहीं है, लेकिन यह निश्चित रूप से मदद करता है।
क्रेग गिदनी

ज़रुरी नहीं। आप गैर-प्रतिबिंब भाषाओं में ठीक कर सकते हैं।
बिली ओनेल

-2

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

और यदि आप किसी भी .class फ़ाइल (जावा में) का कोड देखना चाहते हैं तो कई डिकम्प्रेसर मुफ्त उपलब्ध हैं!


अपघटन एक परावर्तन सुविधा नहीं है।
बिली ओनेल

हां, यह नहीं है ... लेकिन मेरा कहने का मतलब यह था कि अगर u प्रतिबिंब की तरह प्रयोग करते समय धोखा महसूस करते हैं (जो आपको जावा में किसी भी वर्ग का विवरण प्रदान करते हैं) तो गलत हैं bcoz प्रतिबिंब एक बहुत ही उपयोगी अवधारणा है और यदि किसी का विवरण मिल रहा है वर्ग वह है जो आपके बारे में है कि किसी भी डिकंपाइलर के साथ आसानी से किया जा सकता है ...
ANSHUL JAIN

2
प्रतिबिंब कुछ मामलों में एक उपयोगी अवधारणा है, हां। लेकिन ९९.९% समय मैं इसे इस्तेमाल करते हुए देख रहा हूं, मैंने देखा कि यह एक डिज़ाइन त्रुटि के आसपास हैक करने के लिए उपयोग किया जाता है।
बिली ओनेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.