2009-06-22 15 views
10

जावा प्रतिबिंब रनटाइम पर ऑब्जेक्ट को आत्मनिरीक्षण करने के लिए एक तंत्र प्रदान करता है। कोई दूसरा विचार नहीं, यह एक महान विशेषता है, लेकिन यह सभी रिफैक्टरिंग सम्मेलनों को तोड़ देती है!जावा प्रतिबिंब और रिफैक्टरिंग में दर्द

आधुनिक आईडीई में भी कोई आसान तरीका नहीं है (यहां तक ​​कि File Search के अलावा) यह जानने के लिए कि किस विशेषता का संदर्भ दिया गया है और कहां है। यह रिफैक्टरिंग को और अधिक जटिल (थकाऊ!) और त्रुटि प्रवण बनाता है।

फ़्रैंक होने के लिए, यह केवल Reflection API नहीं है; Hibernate mapping files (hbm.xml) और JSP files दोनों स्ट्रिंग के रूप में गुणों को संदर्भित करते हैं और जब आप अपने विशेषता नाम को दोबारा बदलते हैं, तो आपको इन सभी स्थानों में मैन्युअल रूप से बदलना होगा।

इससे भी बदतर, हाइबरनेट मैपिंग फ़ाइलों या जेएसपी फ़ाइलों में हुए परिवर्तनों में रनटाइम त्रुटियां होती हैं।

मुझे यह जानने में दिलचस्पी है कि अन्य प्रोग्रामर जावा में इसे कैसे प्रबंधित करते हैं। क्या कुछ उपकरण हैं? मैं मुख्य विकास मंच के रूप में ग्रहण/आईबीएम आरएडी का उपयोग करता हूं। आम तौर पर हम विशेषता को परिभाषित करने के लिए constant का उपयोग करते हैं और जब भी संभव हो इसका उपयोग करते हैं लेकिन यह हमेशा संभव नहीं होता है।

मुझे भी दिलचस्पी होगी कि अन्य भाषाओं को कैसे संभाला जाए!

+1

इंटेलिजे के पास इन दिनों जेएसपी, स्प्रिंग और हाइबरनेट कॉन्फ़िगरेशन फाइलों में बहुत अच्छे हुक हैं, जिनमें से सभी 'जागरूक प्रतिक्रिया' हैं। मैं ग्रहण उपयोगकर्ता नहीं हूं लेकिन मैंने सोचा कि इसमें कुछ भी समान था। –

+0

भी नेटबीन के कुछ स्मार्ट रिफैक्टरिंग टूल (वसंत, वेब.एक्सएमएल, आदि) – dfa

+0

मुझे लगता है कि ग्रहण भी हाइबरनेट फ़ाइलों में रिफैक्टर कर सकता है। –

उत्तर

7

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

और हां, गतिशील रूप से टाइप की गई भाषाओं (या प्रतिबिंब के भारी उपयोग) के साथ, रेफैक्टरिंग कठिन है। आपको अच्छा ग्रहण रिफैक्टरिंग क्षमताओं नहीं मिलते हैं। इसके बजाय, grep आपका दोस्त बन जाता है।

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

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

+0

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

2

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

इसके अलावा, यही कारण है कि आप अपने कोड में इसका उपयोग करने से पहले विशेष देखभाल और विचार का उपयोग किया जाना चाहिए।

लेकिन प्रतिबिंब के साथ यह समस्या यह है कि एनोटेशन का उपयोग क्यों अधिक लोकप्रिय हो रहा है। एनोटेशन का उपयोग करते समय समस्या कम हो जाती है।

लेकिन मुझे बताएं, जैसा कि पिछली पोस्ट सही मायने में बताती है, अगर आपके पास यूनिट परीक्षणों का कोई भी अच्छा सुरक्षा नेट नहीं है, तो आप किसी भी प्रकार के प्रतिबिंब का उपयोग करते हैं, चाहे आप बहुत सारे प्रतिबिंब का उपयोग करते हैं या नहीं, खतरनाक है।

+0

एनोटेशन इस तरह के परिदृश्यों में समस्या का समाधान कैसे करता है? क्या आप एक उदाहरण दे सकते हैं? धन्यवाद। – lud0h

+0

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

0

आप इंटेलिजे आईडीईए का उपयोग करने में रुचि रखते हैं, जो टिप्पणियों और स्ट्रिंग स्थिरांक में रिफैक्टर कक्षा के नामों की खोज भी करेगा।

+0

नेटबीन्स (और संभावित रूप से अन्य) भी – dfa

+1

ग्रहण (और संभवतः नेटबीन) भी ऐसा कर सकते हैं - लेकिन यह अभी भी काम करने की गारंटी नहीं है, क्योंकि यह केवल पूरी तरह से योग्य वर्ग नाम –

0

ठीक है, यह आईडीई के लिए एक और मौका है जो महंगा प्रीमियम संस्करण बेचता है जो विशिष्ट कॉन्फ़िगरेशन फ़ाइलों में उपयोग किए जाने वाले वर्ग नामों को पहचान और पुन: सक्रिय करेगा।

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

लेकिन प्रतिबिंब एपीआई के प्रत्यक्ष, "मैनुअल" उपयोग के लिए कोई सामान्य समाधान नहीं है - यही कारण है कि यह आम तौर पर निराश होता है।

+0

पकड़ लेगा समस्या केवल प्रतिबिंब API के साथ नहीं है। हाइबरनेट या जेएसपी जैसी कॉन्फ़िगरेशन फ़ाइलें समयबद्ध संकलित होती हैं और उपकरण उन्हें प्रभावी ढंग से कैप्चर नहीं करते हैं। – lud0h

+0

चूंकि उन फ़ाइलों में एक अच्छी तरह से परिभाषित वाक्यविन्यास है, यह कम से कम संभव है (और बहुत मुश्किल नहीं)। –

1

भाषा में अधिक "शाब्दिक" पेश करके रिफैक्टरिंग में सुधार किया जा सकता है। जैसे imho .class शाब्दिक कुछ मॉडलों की संकलन-समय सुरक्षा सुनिश्चित करने का एक शानदार तरीका है। हालांकि यहां कहने की महत्वपूर्ण बात यह है कि, कभी-कभी, मैं संकलन-समय सुरक्षा खोना चाहता हूं। स्ट्रिंग्स दो परतों के बीच एक कमजोर युग्मित अनुबंध व्यक्त करने का सबसे सरल लेकिन शक्तिशाली तरीका है क्योंकि आप नियमित अभिव्यक्ति, आदि

प्रतिबिंब की वास्तविक समस्या एपीआई का वर्बोज़ उपयोग है। लचीलापन के लिए प्रमुख लागत है।

पुनश्च

परियोजना सिक्का कुछ नए भाषा निर्माण भविष्य में कहीं परिचय सकता है इस क्षेत्र को बढ़ाने के लिए।

0

एक तरफ के रूप में, प्रतिबिंब भी मुद्दों का कारण बनता है यदि आप अपने कोड को obfuscation के माध्यम से सुरक्षित करना चाहते हैं। विशिष्ट obfuscation उपकरण अब आपको उन सभी फ़ाइलों की एक सूची बनाए रखने की आवश्यकता है जिन्हें आप obfuscated नहीं चाहते हैं ताकि सभी XML कॉन्फ़िगरेशन फ़ाइलों से प्रतिबिंब ठीक से काम करता हो।

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

0

टैगगिन कक्षाओं, विधियों, फ़ील्ड के बारे में क्या आपको पता है प्रतिबिंब द्वारा उपयोग किया जाता है? जब आप अपना नाम बदलते हैं तो आईडीई आपको चेतावनी दे सकता है।

0

आप dp4j.com के साथ प्रतिबिंब API लिखने से बच सकते हैं जब आप संकलित समय को जानते हैं कि आप क्या खोज रहे हैं।

एक्सएमएल मैपिंग के बारे में, वे एक दर्द कर रहे हैं, मैं भी और JPA2 के साथ ऐसा कम NetBeans प्लेटफार्म के साथ अनुभव किया। अच्छी खबर यह है कि एनोटेशन खत्म हो रहे हैं, और यह फिर से संकलन-समय की जांच प्रदान करता है। मुझे हाइबरनेट के बारे में निश्चित नहीं है, लेकिन जेपीए और नेटबीन (more as of 7) दोनों एक्सएमएल मैपिंग के एनोटेशन समकक्ष प्रदान करते हैं।

मैं भी SqlWrapper विकसित की थी JDBC के साथ तार का उपयोग कर से दूर होने की। अधिक परिष्कृत (और जटिल) जेपीए 2 के मानदंड एपीआई है।

2

हमने वास्तव में एक ग्रहण प्लगइन विकसित किया है जो इस समस्या का काफी हद तक ख्याल रखता है। इसे रिफाफ्लेक्स कहा जाता है: http://www.feu.de/ps/prjs/rf/

संबंधित मुद्दे