2008-10-29 19 views
5

मुझे कुछ समय पहले मिला (और मैं फिर से पुष्टि करना चाहता हूं) कि यदि आप कक्षा स्तर परिवर्तनीय घोषित करते हैं, तो आपको क्लास कन्स्ट्रक्टर या लोड कहलाए जाने तक अपने कन्स्ट्रक्टर को कॉल नहीं करना चाहिए। कारण प्रदर्शन था - लेकिन ऐसा करने के अन्य कारण हैं या नहीं? क्या इस नियम में अपवाद हैं?चर घोषित करना - सर्वोत्तम प्रथाओं

अर्थात्:

public class SomeClass 
{ 
    private PersonObject _person; 

    public SomeClass() 
    { 
     _person = new PersonObject("Smitface"); 
    } 
} 

करने का विरोध किया:

public class SomeClass 
{ 
    private PersonObject _person = new PersonObject("Smitface"); 

    public SomeClass() 
    { 

    } 
} 

उत्तर

12

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

नेसियो ने कुछ कन्स्ट्रक्टर विफलताओं के बारे में आपके आवेदक पर क्या प्रभाव डाला था इसके बारे में बात की।

इसी कारण से, मैं हमेशा विकल्प # 1 का उपयोग करता हूं।

+0

तथ्य यह है कि एक निर्माता विफल हो सकता है और आप # 2 में त्रुटि को संभाल नहीं सकते हैं # 1 का उपयोग करने का वास्तव में एक अच्छा कारण है: इस मामले में यह शैली लेकिन विश्वसनीयता के बारे में नहीं है। –

+0

पहली शैली चुनने का अच्छा कारण। –

+1

"हैंडलिंग" की आपकी वर्तनी ने मुझे "जॉर्ज के इतिहास" और "हेवनिंग" की वर्तनी की याद दिला दी। स्मृति के लिए +1। – StingyJack

0

मैं उत्तरार्द्ध पसंद करते हैं, लेकिन केवल क्योंकि यह है कि मैं क्या मैं क्या सोचता सबसे अच्छा अभ्यास है के आधार पर करते है मुझे यह साफ-सुथरा लगता है।

यह व्यक्तिगत वरीयता वास्तव में है, वे दोनों एक ही काम करते हैं।

6

ईमानदारी से, यदि आप आईएल देखते हैं, तो दूसरे मामले में जो भी होता है वह है कि कंपाइलर आपके लिए कन्स्ट्रक्टर को प्रारंभिक बनाता है।

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

-3

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

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

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

+0

आपकी टिप्पणी वास्तव में यहाँ लागू नहीं होता। वेरिएबल्स को उसी समय शुरू किया जा रहा है, भले ही किस विधि का उपयोग किया जाता है। – Herms

+0

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

1

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

+0

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

0

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

+0

स्टेटिक कन्स्ट्रक्टर? मुझे इस उदाहरण में कुछ भी स्थिर नहीं दिख रहा है। –

0

मुझे कन्स्ट्रक्टर में प्रारंभ करना पसंद है क्योंकि इस तरह यह सब एक ही स्थान पर होता है, और क्योंकि यह बाद में ओवरलोडेड कन्स्ट्रक्टर बनाने का निर्णय लेता है, तो यह आसान बनाता है।

इसके अलावा, यह उन चीजों को याद दिलाने में मदद करता है जिन्हें मैं एक deconstructor में साफ करना चाहता हूं।

0

बाद आलसी इन्स्टेन्शियशन का लाभ ले सकते हैं, जैसे कि यह चर को प्रारंभ नहीं होंगे जब तक यह

0

संदर्भित है मुझे लगता है कि प्रश्न के इस प्रकार केवल शैलीगत है, इसलिए कौन परवाह करता है किस तरह से आप यह कर। भाषा दोनों की अनुमति देता है, इसलिए अन्य लोग दोनों करने जा रहे हैं। बुरा धारणा मत करो।

4

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

एरिक लिपर्ट से this post और this post देखें जो दोनों के बीच अर्थपूर्ण अंतर को विस्तार से बताता है।

तो जवाब है कि अधिकांश मामलों में यह कोई फर्क नहीं है, और यह निश्चित रूप से प्रदर्शन के मामले में कोई फर्क नहीं है, लेकिन मामलों की एक अल्पमत में यह एक फर्क कर सकता है, और आपको पता होना चाहिए कि क्यों, और उस पर आधारित निर्णय लेना चाहिए।

1

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

बेशक, यह केवल तभी गिना जाता है जब कन्स्ट्रक्टर प्रारंभिकरण (जैसा कि डिस्कोरैक्स द्वारा उल्लिखित) का उपयोग करने के लिए कोई अनिवार्य कारण नहीं है।

2

निर्भरता इंजेक्शन या इनवर्जन ऑफ कंट्रोल (आईओसी) नामक एक आम पैटर्न है जो एक निर्भर वस्तु (जैसे डीएएल कक्षा) को "इंजेक्शन" के लिए इन दो तंत्रों को एक वर्ग में प्रदान करता है जो निर्भरता श्रृंखला को आगे बढ़ाता है (से आगे डेटाबेस)

इस पद्धति में, एक ctor का उपयोग कर, क्या तुम करोगी

सार्वजनिक वर्ग SomeClass
{
प्रति निजी PersonObject;

public SomeClass(PersonObject person) 

{  
    per = person; 
} 

}

निजी PersonObject जो = नए PersonObject ("Smitface");

कुछ क्लास MyObj = नया SomeClass (जो);

अब आप उदाहरण के लिए, उत्पादन कॉल या एक इकाई परीक्षण विधि में एक परीक्षण दाल वर्ग के लिए एक असली दाल कक्षा में पास कर सकता है ...

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