क्या नई वस्तुओं को बिना स्टोर किए बनाना बुरा व्यवहार है?


23

मैंने ऑब्जेक्ट के संदर्भ को संग्रहीत किए बिना जावा कोड में बनाई गई वस्तुओं को देखा है। उदाहरण के लिए, एक ग्रहण प्लगइन में मैंने एक SWT शेल बनाया है, जो इस प्रकार है:

new Shell();

यह नया शेल ऑब्जेक्ट एक चर में संग्रहीत नहीं है, लेकिन जब तक खिड़की का निपटान नहीं किया जाता है, तब तक यह संदर्भित रहेगा कि [मुझे विश्वास है?] डिफ़ॉल्ट रूप से तब होता है जब खिड़की बंद होती है।

क्या उनके संदर्भ को संचित किए बिना इस तरह की वस्तुओं का निर्माण करना बुरा व्यवहार है? या पुस्तकालय खराब डिजाइन किया गया था? क्या होगा यदि मुझे संदर्भ की आवश्यकता नहीं है, लेकिन केवल वस्तु के "दुष्प्रभाव" चाहते हैं? क्या मुझे किसी भी तरह से एक संदर्भ स्टोर करना चाहिए?

अद्यतन करें:

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

(new HelloThread()).start();

यह अभ्यास कई संदर्भों में देखा जाता है, इसलिए प्रश्न बने हुए हैं। क्या यह अच्छा अभ्यास है?


2
संदर्भ को संग्रहीत करने की बात क्या होगी?
डेनियल आर हिक्स

(संभवतः Shell.createTopLevelShell()इस मामले में एक कंस्ट्रक्टर का उपयोग करके, जैसे या जो भी, बनाम एक स्थिर विधि है, यह बेहतर होगा । लेकिन कार्यात्मक रूप से इसमें बहुत अंतर है।)
डैनियल आर हिक्स

क्या यह प्रश्न उन वस्तुओं को बनाने के अभ्यास के बारे में है, जिनके बारे में बात किए बिना, उन कक्षाओं का निर्माण करना है, जिन्हें विशेष रूप से इस अभ्यास की आवश्यकता है या क्या यह SWT इस तरह के पैटर्न का उपयोग करने के तरीके के बारे में है?
स्ट्रिपिंगवर्यर

1
SWT ऑब्जेक्ट्स dispose()d होना चाहिए : नियम 1: यदि आपने इसे बनाया है, तो आप इसे डिस्पोज करते हैं। eclipse.org/articles/swt-design-2/swt-design-2.html
jbindel

2
मैं डिबगिंग उद्देश्यों के लिए एक संदर्भ रखने के लिए एक चर का उपयोग करेगा। यदि आपके पास इस पद्धति का एक विराम बिंदु है, तो आप स्थानीय चर के माध्यम से ऑब्जेक्ट को क्वेरी करने के लिए डिबगर प्राप्त कर सकते हैं। संदर्भ के बिना मुझे यकीन है कि यह संभव है लेकिन शायद बहुत कठिन है।
मार्टिन यॉर्क

जवाबों:


12

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

निम्नलिखित काल्पनिक उदाहरण पर विचार करें:

new SingleFileProcessor().process(file);

यदि हर फ़ाइल के लिए एक नया प्रोसेसर ऑब्जेक्ट बनाया जाना है, और process()कॉल के बाद इसकी आवश्यकता नहीं है , तो इसका संदर्भ संग्रहीत करने का कोई मतलब नहीं है।

यहां एक और उदाहरण दिया गया है, जो कि जावा कंसीलर ट्यूटोरियल से लिया गया है :

(new HelloThread()).start();

मैंने कई अन्य उदाहरण देखे हैं जब संदर्भ संग्रहीत नहीं है, और यह मेरी आंख के लिए बिल्कुल ठीक है, जैसे:

String str = new StringBuilder().append(x).append(y).append(z).toString();

( StringBuilderवस्तु नहीं रखी गई है।)

इसी तरह के पैटर्न हैं जिनमें common.lang का HashCodeBuilderएट अल शामिल है।


2
@ बाल्सक: सम्मान के साथ, मैं यह नहीं देखता कि यह क्या गड़बड़ कर देता है और किस तरीके से कारखाने का तरीका बेहतर है (मुझे लगता है कि आपका उदाहरण मेरा अनुरूप है, और getInstance()एक कारखाना है और एक सिंगलटन नहीं है)।
एनपीई

यह कारखाने के ऊपर है कि एक सिंगलटन का उपयोग करना है या नहीं। कारखाने के कॉलर को इसके बारे में बहुत अधिक नहीं सोचना चाहिए।
डोनल फैलो

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

@BalusC: FileProcessor के व्यवहार को बदलने के लिए अतिरिक्त तरीके हो सकते हैं process
केविन क्लाइन

7

यदि आपको बनाई गई वस्तु के संदर्भ की आवश्यकता नहीं है , तो संदर्भ पर पकड़ न रखें। यह इतना सरल है।


5

सामान्य तौर पर, संदर्भों को जल्द से जल्द जारी करना अच्छा होता है क्योंकि वे यथोचित रूप से जारी किए जा सकते हैं। मुझे इसमें कोई अंतर नहीं दिखता है:

HelloThread thread = new HelloThread();
thread.start();
// where thread is never used for the rest of the method

तथा

(new HelloThread()).start();

जहां तक ​​कोड का सवाल है, आप केवल एक चर नाम के उपयोग से बच रहे हैं, जो एक सकारात्मक बात हो सकती है। जेआईटी कंपाइलर आम तौर पर यह पहचानने के लिए पर्याप्त स्मार्ट है कि कचरा इसके अंतिम उपयोग के बाद थ्रेड इकट्ठा कर सकता है, इसलिए प्रदर्शन के दृष्टिकोण से शायद कोई अंतर नहीं है।

बचने के लिए एकमात्र वास्तविक मुद्दा कंस्ट्रक्टर विरोधी पैटर्न में कोड है , लेकिन यह ध्वनि नहीं है जैसा कि आप पूछ रहे हैं।


3

यदि आप SWT का उपयोग कर रहे हैं, तो यह बुरा हो सकता है, क्योंकि वहां आपको अपने आप को साफ करना होगा (निपटान () विधि को कॉल करके)। लेकिन अन्य वर्गों (गैर SWT) के लिए यह ठीक है।

यहाँ ऑपरेटिंग ऑपरेटिंग सिस्टम संसाधन के बारे में एक लेख है


परिपत्र संदर्भ वस्तुओं को जावा में एकत्र होने वाले कचरे से नहीं रोकता है। कोई भी आधुनिक जावा वीएम यह निर्धारित करता है कि क्या वस्तुएं पठनीय हैं या नहीं, यह इस आधार पर है कि वे पहुंच योग्य नहीं हैं, और संदर्भ गिनती का उपयोग नहीं करती हैं।
jbindel

2
वास्तव में यह संदर्भ गिनती का उपयोग नहीं करता है। लेकिन SWT एक विशेष मामला है जहां हमें डिस्पोज () को कॉल करने की आवश्यकता होती है, हालांकि पहले किसी भी रिटेन () को कॉल करने की आवश्यकता नहीं है।
एलेक्स

मेरा मतलब केवल गैर-एसडब्ल्यूटी मामले का उल्लेख करना था।
jbindel

यहाँ ऑपरेटिंग सिस्टम रिसोर्सेस के बारे में एक लेख है eclipse.org/articles/swt-design-2/swt-design-2.html
एलेक्स

2
उस मामले में "जीसी के लिए असंभव" के बारे में बयान को हटाने के लिए अपने जवाब को संपादित करें क्योंकि यह भ्रामक है।
डोनाल्ड फेलो

1

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

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

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


2
क्या अन्य भाषाओं के कष्टप्रद प्रोग्रामर के बारे में चिंता करना वास्तव में पहली चिंता है?
बटंस Butt४०

यह आपकी टीम की संरचना के आधार पर इसे पठनीयता / परिचितता / शैली का मुद्दा बनाता है, क्योंकि यह एक शैली है जिसे बहुत से लोग आगे ले जाते हैं। यहां तक ​​कि जिन लोगों ने कभी C ++ में प्रोग्राम नहीं किया है, वे अक्सर अपने गुरुओं की शैलियों को अपनाते हैं जिन्होंने किया था।
कार्ल बेज़ेलफेल्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.