ऐसे तरीके बनाएं जो उदाहरण के क्षेत्रों, स्थिर पर निर्भर न हों?


19

हाल ही में मैंने Groovy में एक जावा प्रोजेक्ट के लिए इंटीग्रेशन टेस्टिंग फ्रेमवर्क के लिए प्रोग्रामिंग शुरू की। मैं Groovy प्लग-इन के साथ Intellij IDEA का उपयोग करता हूं और मुझे उन सभी तरीकों के लिए एक चेतावनी के रूप में देखकर आश्चर्य होता है जो गैर-स्थिर हैं और किसी भी उदाहरण फ़ील्ड पर निर्भर नहीं हैं। जावा में, हालांकि, यह एक मुद्दा नहीं है (कम से कम आईडीई के दृष्टिकोण से)।

क्या सभी विधियाँ जो किसी भी प्रकार के क्षेत्रों पर निर्भर नहीं होती हैं उन्हें स्थैतिक कार्यों में बदल दिया जाना चाहिए? यदि सही है, तो क्या यह ग्रूवी के लिए विशिष्ट है या यह सामान्य रूप से OOP के लिए उपलब्ध है? और क्यों?


क्या ये विधियाँ अन्य उदाहरण विधियों को कहते हैं? या क्या उनका शाब्दिक रूप से उस वर्ग की किसी वस्तु से कोई लेना देना नहीं है? क्या आप एक उदाहरण दे सकते हैं?
रे तोल

जवाबों:


26

ध्यान दें कि IDEA का यह निरीक्षण जावा के लिए भी है, इसे विधि कहा जाता है 'स्थैतिक' ,

यह निरीक्षण किसी भी तरीके की रिपोर्ट करता है जिसे सुरक्षित रूप से स्थैतिक बनाया जा सकता है। एक विधि स्थिर हो सकती है यदि वह अपनी कक्षा के गैर-स्थिर तरीकों और गैर-स्थिर क्षेत्रों का संदर्भ नहीं देती है और उप-वर्ग में ओवरराइड नहीं होती है ...

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

शुरू करने के लिए, आधिकारिक जावा ट्यूटोरियल बल्कि स्थिर है जब तरीकों को स्थिर होना चाहिए:

स्थैतिक तरीकों के लिए एक आम उपयोग स्थैतिक क्षेत्रों का उपयोग करना है।

ऊपर दिए गए, कोई यह तर्क दे सकता है कि डिफ़ॉल्ट रूप से उल्लिखित निरीक्षण को चालू करने से जावा में स्थिर संशोधक के अनुशंसित उपयोग का अनुपालन नहीं होता है।

इसके अलावा, कुछ अन्य स्रोत भी हैं जो इस निरीक्षण के पीछे झूठ बोलने वाले विचारों का उपयोग करने या यहां तक ​​कि इसे हतोत्साहित करने के लिए विवेकपूर्ण दृष्टिकोण का सुझाव देने के रूप में जाते हैं।

उदाहरण के लिए देखें जावा वर्ल्ड लेख - मिस्टर हैप्पी ऑब्जेक्ट स्टैटिक विधियाँ सिखाता है :

उदाहरण के लिए स्वतंत्र होने की कोई भी विधि स्टेटिक होने के लिए एक उम्मीदवार है।

ध्यान दें कि मैं कहता हूं "उम्मीदवार को स्थिर घोषित किया जा रहा है।" पिछले उदाहरण में भी कुछ भी आपको instances()स्थिर घोषित करने के लिए मजबूर नहीं करता है। इसे स्थिर के रूप में घोषित करना केवल कॉल करने के लिए अधिक सुविधाजनक बनाता है क्योंकि आपको विधि को कॉल करने के लिए किसी उदाहरण की आवश्यकता नहीं है। कभी-कभी आपके पास ऐसी विधियाँ होंगी जो उदाहरण स्थिति पर भरोसा नहीं करती हैं। आप इन तरीकों को स्थिर नहीं बनाना चाह सकते हैं। वास्तव में आप शायद उन्हें केवल स्थिर के रूप में घोषित करना चाहते हैं यदि आपको उन्हें बिना किसी उदाहरण के उपयोग करने की आवश्यकता है।

इसके अलावा, भले ही आप इस तरह की विधि को स्थैतिक घोषित कर सकते हैं, हो सकता है कि आप वंशानुक्रम के मुद्दों के कारण ऐसा न चाहें कि यह आपके डिजाइन में हस्तक्षेप करता हो। कुछ ऐसे मुद्दों को देखने के लिए "प्रभावी ऑब्जेक्ट-ओरिएंटेड डिज़ाइन" पर एक नज़र डालें जो आपके सामने होंगे ...

Google परीक्षण ब्लॉग पर एक लेख यहां तक ​​जाता है कि स्टैटिक मेथड्स का दावा है डेथ टू टेस्टिबिलिटी :

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

कभी-कभी एक स्थिर विधियाँ अन्य वस्तुओं का कारखाना होता है। यह परीक्षण समस्या को और बढ़ा देता है। परीक्षणों में हम इस बात पर भरोसा करते हैं कि हम वस्तुओं को विभिन्न प्रकार से महत्वपूर्ण निर्भरता के स्थान पर मोक्स से तार कर सकते हैं। एक बार एक newऑपरेटर को बुलाया जाता है, हम उप-वर्ग के साथ विधि को ओवरराइड नहीं कर सकते हैं। इस तरह के एक स्थैतिक कारखाने का एक कॉलर स्थायी रूप से कंक्रीट वर्गों से जुड़ा होता है, जो कि स्थैतिक कारखाने विधि द्वारा उत्पादित होता है। दूसरे शब्दों में स्थैतिक विधि की क्षति स्थैतिक विधि से कहीं अधिक है। स्थैतिक विधि में वस्तु ग्राफ वायरिंग और निर्माण कोड अतिरिक्त खराब है, क्योंकि ऑब्जेक्ट ग्राफ वायरिंग कैसे हम परीक्षण के लिए चीजों को अलग करते हैं ...


आप देखते हैं, ऊपर दिया गया यह केवल प्राकृतिक लगता है कि उल्लेखित निरीक्षण जावा के लिए डिफ़ॉल्ट रूप से बंद है।

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

ग्रूवी के लिए, चीजें काफी अलग हैं। ऊपर सूचीबद्ध कोई भी तर्क लागू नहीं होता है, विशेष रूप से टेस्टीबिलिटी के बारे में, जैसा कि समझाया गया है जैसे जावालॉबी में ग्रूवी लेख में मॉकिंग स्टैटिक मेथड्स :

यदि आप जिस ग्रूवी क्लास का परीक्षण कर रहे हैं, वह किसी अन्य ग्रूवी वर्ग पर एक स्थिर विधि को कॉल करता है, तो आप एक्सपेंडेमोटेक्लास का उपयोग कर सकते हैं जो आपको विधिपूर्वक तरीके, निर्माणकर्ता, गुण और स्थैतिक विधियों को जोड़ने की अनुमति देता है ...

इस अंतर की संभावना है कि ग्रूवी में उल्लिखित निरीक्षण के लिए डिफ़ॉल्ट सेटिंग विपरीत है। जबकि जावा डिफ़ॉल्ट में "ऑन" ग्रूवी में उपयोगकर्ताओं के भ्रम का स्रोत होगा, एक विपरीत सेटिंग आईडीई उपयोगकर्ताओं को भ्रमित कर सकती है।

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


वैसे, ReSharper (C # / विजुअल स्टूडियो के लिए JetBrains द्वारा बनाया गया) एक ही बात बताता है
कोनराड मोरावस्की

6
साइड इफेक्ट के साथ और बिना स्थिर तरीकों के बीच एक महत्वपूर्ण अंतर है। Google अर्क वास्तव में पूर्व को संबोधित करता है।
२३:४३ पर assylias

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

5

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

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


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

2
@ user40980 यह विचार करने योग्य है, सच है, लेकिन यह भी विचार करने योग्य है कि विरासत एक भद्दा उपकरण हो सकता है जिसका अक्सर दुरुपयोग किया जाता है, और कई प्रमुख आंकड़े तर्क देते हैं कि सभी वर्गों को finalया विशेष रूप से मन में निहित होना चाहिए ।
सारा

3

मुझे लगता है कि स्पॉट किए जाने के लिए संभव रिफैक्टरिंग को सक्षम करना है ।

एक बार विधि को स्थिर बना देने के बाद, यह स्पष्ट है कि इसे कक्षा से बाहर ले जाया जा सकता है, एक एकता वर्ग से कहें।

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


-1

ध्यान दें कि आपके पास कुछ इंटरफ़ेस लागू करने वाली स्टेटलेस कक्षाएं हो सकती हैं (जैसे java.lang.Runnable- आप उनके तरीकों को स्थिर नहीं बना सकते। कुछ पैटर्न (जैसे रणनीति) स्टेटलेस ऑब्जेक्ट्स भी उत्पन्न कर सकते हैं जिनमें कई तरीके भी हो सकते हैं।

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


यह पूछे गए प्रश्न का उत्तर कैसे देता है?
gnat

1
किसी राज्य से किसी राज्य में जाना कठिन क्यों है? मैं कहूंगा कि यह दूसरा रास्ता है। कुछ दूषित को शुद्ध करने की तुलना में कुछ दूषित करना आसान है।
सारा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.