2009-02-13 7 views
5

मैंने हाल ही में एक नई परियोजना शुरू की है और मैं अपने आवृत्ति चर को हमेशा कुछ मूल्य के लिए प्रारंभ करने की कोशिश कर रहा हूं, इसलिए उनमें से कोई भी शून्य नहीं है। नीचे छोटा सा उदाहरण:क्या मुझे हमेशा जावा में इंस्टेंस वैरिएबल रखना चाहिए या नहीं?

public class ItemManager { 

    ItemMaster itemMaster; 
    List<ItemComponentManager> components; 

    ItemManager() { 
    itemMaster = new ItemMaster(); 
    components = new ArrayList<ItemComponentManager>(); 
    } 

    ... 
} 

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

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

+0

कभी भी इसे बाद में फेंकने के लिए खाली खाली ऐरेलिस्ट बनाएं। खाली, अपरिवर्तनीय संग्रह प्राप्त करने के लिए हमेशा संग्रह कक्षा में विधियों में से एक का उपयोग करें। –

+0

अब तक के उत्तरों के लिए धन्यवाद, कुछ मूल्यवान इनपुट मिला। – MicSim

उत्तर

9

मैं आमतौर पर एक खाली संग्रह और दो अलग अलग चीजें हैं के रूप में एक अशक्त संग्रह का इलाज:

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

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

0

अगर आपके तरीकों में से एक में आप

itemMaster = null; 

सेट या आप कुछ अन्य वर्ग के लिए ItemManager के लिए एक संदर्भ लौट सकते हैं और यह शून्य के रूप में itemMaster सेट क्या होता है। (आप इसके खिलाफ आसानी से अपने आइटम प्रबंधक आदि का क्लोन वापस कर सकते हैं)

मैं चेक को यथासंभव रखता हूं।

+0

कि अशक्त-सेटिंग मैं डिजाइन द्वारा क्या परहेज कर रहा हूँ (अलिखित नियम के रूप में) है: कोई विधि कभी "itemMaster = अशक्त" – MicSim

+0

कॉल करेंगे और एक संदर्भ (परिवर्तनशील वर्गों के लिए) अंतिम उपयोग करके रीसेट करने लागू कर सकते हैं। – gimpf

+0

बाहरी कोड सेटिंग आइटम आइटम के संदर्भ में इसका कोई प्रभाव नहीं पड़ेगा। यह वस्तु के स्थानीय संदर्भ को हटा देगा। यह ऑब्जेक्ट के आंतरिक संदर्भ को साफ़ नहीं करेगा या ऑब्जेक्ट को नष्ट नहीं करेगा। – Clayton

1

हां, कन्स्ट्रक्टर में सभी वर्ग चर शुरू करना बहुत अच्छा विचार है।

0

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

3

मैं कहूंगा कि यह बिल्कुल ठीक है - बस जब तक आपको याद है कि आपके पास "खाली" प्लेसहोल्डर मूल्य है और असली डेटा नहीं है।

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

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

+0

मैं रक्षात्मक कोडिंग पर महत्वपूर्ण राय देता हूं। सभी अक्सर "रक्षात्मक" केवल तर्क त्रुटियों को छुपाते हैं, और मैंने अक्सर रक्षात्मक चले गए बुरे को देखा है। बहुत कम अक्सर मैं एक असफल गति के साथ समस्या होगी। – gimpf

+0

"रक्षात्मक" उचित त्रुटि रिपोर्टिंग के साथ किसी भी तर्कसंगत त्रुटियों को छिपाना नहीं चाहिए। यदि आप शून्य की जांच करते हैं और शून्य की स्थिति में त्रुटि की रिपोर्ट करते हैं तो आप रक्षात्मक हैं और आप संभावित रूप से उत्पादन अनुप्रयोग को मारने के बिना तार्किक त्रुटियों को तुरंत और आसानी से खोज सकते हैं। –

1

बिंदु कोड में कहीं एक वर्ग चर उपयोग करने से पहले अशक्त के लिए थकाऊ चेकिंग से बचने के लिए मुख्य रूप से है।

आपको अभी भी शून्य की जांच करनी है। तीसरे पक्ष के पुस्तकालयों और यहां तक ​​कि जावा एपीआई कभी-कभी शून्य वापस आ जाएगी।

इसके अलावा, किसी ऑब्जेक्ट को तुरंत चालू करना कभी भी बर्बाद नहीं होता है, लेकिन यह आपकी कक्षा के डिज़ाइन पर निर्भर करेगा।

2

मैं उन्हें अंतिम यदि संभव हो तो उन्हें बना दूंगा। फिर उन्हें कन्स्ट्रक्टर में शुरू किया जाना चाहिए और शून्य नहीं हो सकता है।

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

+0

अंतिम !? यह किसी भी adhoc (डी) serialization करना मुश्किल बनाता है। एक डीबी के लिए बने रहना मुश्किल हो जाता है। कक्षा को विस्तार करना भी दर्द बन जाता है। – Pat

+0

@Pat YAGNI (आपको इसकी आवश्यकता नहीं होगी)। सबक्लास किसी भी सुपरक्लास की निजी स्थिति तक नहीं पहुंच सकते हैं, और यह एक अच्छी बात है। – eljenso

2

मैं कुछ मामलों में आया हूं जहां इससे समस्याएं आती हैं। deserialization के दौरान, कुछ ढांचे कन्स्ट्रक्टर को कॉल नहीं करेंगे, मुझे नहीं पता कि वे ऐसा करने के लिए कैसे या क्यों चुनते हैं लेकिन ऐसा होता है। इसके परिणामस्वरूप आपके मान null हो सकते हैं। मैं उस मामले में भी आया हूं जहां निर्माता को बुलाया जाता है लेकिन किसी कारण से सदस्य चर प्रारंभ नहीं होते हैं।

वास्तविक तथ्य में मैं तुम्हारा के बजाय निम्नलिखित कोड का उपयोग करेंगे:

public class ItemManager { 

    ItemMaster itemMaster = new ItemMaster(); 
    List<ItemComponentManager> components = new ArrayList<ItemComponentManager>(); 

    ItemManager() { 
    ... 
    } 
    ... 
} 
1

एक वस्तु के उपयोग के लिए 100% तैयार हो जाना चाहिए के बाद यह निर्माण किया है। उपयोगकर्ताओं को नल के लिए जांच नहीं करनी चाहिए। रक्षात्मक प्रोग्रामिंग जाने का तरीका है - चेक रखें।

डीआरवाई के हित में, आप चेक को सेटर्स में डाल सकते हैं और बस कन्स्ट्रक्टर उन्हें कॉल कर सकते हैं। इस तरह आप दो बार चेक कोड नहीं करते हैं।

+0

किसी कन्स्ट्रक्टर से सेटर्स को कॉल करने के बारे में सावधान रहें - यदि उप-वर्ग सेटर्स को ओवरराइड करता है, तो सबक्लास प्रारंभ होने से पहले आप सबक्लास कोड को कॉल कर सकते हैं! –

+0

लेकिन अगर मैं कक्षा ए के निर्माता में हूं, और यह अपने स्वयं के सेटर्स को कॉल करता है, तो सबक्लास बी उन्हें कैसे ओवरराइड करता है? "यह" ए के एक उदाहरण को इंगित करता है, इसलिए मैं अपने कन्स्ट्रक्टर में एक सेटर्स को बुला रहा हूं, बी नहीं? – duffymo

+0

@ कफिमो 'यह' एक निर्माता में हमेशा निर्मित वस्तु को संदर्भित करता है। 'यह' का स्थिर प्रकार वह वर्ग है जिसमें यह प्रतीत होता है। रनटाइम प्रकार उसी वर्ग या उस वर्ग के किसी भी उप-वर्ग हो सकता है। – eljenso

4

सबसे पहले, सभी गैर अंतिम उदाहरण चर घोषित किया जाना चाहिए निजी यदि आप नियंत्रण बनाए रखने के लिए करना चाहते हैं!

रूप में अच्छी तरह आलसी इन्स्टेन्शियशन पर विचार करें - यह भी बचा जाता है "बुरा राज्य" लेकिन उपयोग पर केवल initializes:

class Foo { 
    private List<X> stuff; 
    public void add(X x) { 
     if (stuff == null) 
      stuff = new ArrayList<X>(); 
     stuff.add(x); 
    } 
    public List<X> getStuff() { 
     if (stuff == null) 
      return Collections.emptyList(); 
     return Collections.unmodifiableList(stuff); 
    } 
} 

(नोट Collections.unmodifiableList के उपयोग - जब तक आप वास्तव में एक फोन करने वाले सक्षम होना चाहते हैं अपनी सूची से जोड़ने/निकालने के लिए, आपको इसे अपरिवर्तनीय बनाना चाहिए)

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

इसके अलावा, यह वास्तव में स्वाद का विषय है और यदि आप निर्माण करते समय सार्थक मूल्य प्राप्त कर सकते हैं।

आप एक डि/आईओसी के साथ काम कर रहे हैं, तो आप ढांचे आप के लिए काम करने के लिए चाहते हैं (हालांकि आप यह निर्माता इंजेक्शन के माध्यम से कर सकता है, मैं setters पसंद करते हैं) - स्कॉट

+0

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

+0

सबक्लास उन्हें शून्य पर सेट कर सकता है। – recursive

+0

इंस्टेंस फ़ील्ड उचित encapsulation के लिए निजी होना चाहिए, कभी संरक्षित नहीं। – eljenso

2

तरह से मैं मेरे द्वारा घोषित किसी भी चर के साथ सौदा यह तय करना है कि क्या यह वस्तु के जीवनकाल में बदल जाएगा (या कक्षा स्थिर होने पर)।अगर उत्तर "नहीं" है तो मैं इसे अंतिम बना देता हूं।

आप इसे एक मूल्य देने के लिए जब वस्तु बनाई गई है बनाना यह अंतिम बलों ... व्यक्तिगत रूप से मैं जब तक मैं जानता था कि मैं कम से किस बिंदु को बदलने की जाएगी निम्नलिखित करना होगा:

 
    private final ItemMaster itemMaster; 
    private final List components; 

    // instance initialization block - happens at construction time 
    { 
     itemMaster = new ItemMaster(); 
     components = new ArrayList(); 
    } 

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

+0

या बस निजी अंतिम ItemMaster itemMaster = नए ItemMaster (; निजी अंतिम सूची घटकों = नए ArrayList(); –

+0

मैं प्रारंभ declration से अलग रखना चाहते। – TofuBeer

0

"आइटममेनगर" श्रेणी के नाम से, आइटम मैनेजर कुछ ऐप में सिंगलटन की तरह लगता है। यदि ऐसा है तो आपको जांच करनी चाहिए और वास्तव में, वास्तव में, निर्भरता इंजेक्शन को जानना चाहिए। ItemManager में ItemComponentManagers की सूची बनाने और इंजेक्ट करने के लिए स्प्रिंग (http://www.springsource.org/) जैसे कुछ का उपयोग करें।

डि बिना, गंभीर क्षुधा में हाथ से प्रारंभ डिबग करने के लिए एक बुरा सपना और संकीर्ण परीक्षण बनाने के लिए विभिन्न "प्रबंधक" कक्षाओं को जोड़ने है नरक है।

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

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