एक कंस्ट्रक्टर में कुछ समय (सच) लूप वास्तव में खराब क्यों है?


47

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

किसी ने मुझसे एक दिलचस्प सवाल पूछा जो मेरे लिए था आसानी से जवाब नहीं दिया गया।

क्यों (या यह बिल्कुल भी है?) एक वर्ग के एक निर्माता को कभी न खत्म होने वाले लूप (यानी गेम लूप) शुरू करने के लिए खराब डिजाइन के रूप में माना जाता है?

कुछ अवधारणाएँ हैं जो इससे टूट जाती हैं:

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

और फिर तकनीकी मुद्दे हैं:

  • कंस्ट्रक्टर वास्तव में कभी खत्म नहीं होता है, इसलिए यहां जीसी के साथ क्या होता है? क्या यह वस्तु पहले से ही Gen 0 में है?
  • इस तरह के एक वर्ग से प्राप्त करना असंभव है या कम से कम इस तथ्य के कारण बहुत जटिल है कि बेस कंस्ट्रक्टर कभी नहीं लौटता है

क्या इस तरह के दृष्टिकोण के साथ कुछ और स्पष्ट रूप से बुरा या कुटिल है?


61
क्यों अच्छा है? यदि आप अपने मुख्य लूप को एक विधि (बहुत ही सरल रीफैक्टरिंग) में ले जाते हैं, तो उपयोगकर्ता इस तरह से अस्वाभाविक कोड लिख सकता है:var g = new Game {...}; g.MainLoop();
Brandin

61
आपका प्रश्न पहले से ही इसका उपयोग करने के 6 कारण बताता है, और मैं इसके पक्ष में एक भी देखना चाहता हूं। आप यह भी पूछ सकते हैं कि while(true)प्रॉपर्टी सेटर में लूप डालना क्यों एक बुरा विचार है new Game().RunNow = true:?
ग्रू

38
चरम सादृश्य: हम यह क्यों कहते हैं कि हिटलर ने जो किया वह गलत था? नस्लीय भेदभाव को छोड़कर, WWII शुरू करना, लाखों लोगों की हत्या, हिंसा [आदि आदि 50+ अन्य कारणों से] उसने कुछ भी गलत नहीं किया। यकीन है कि अगर आप कारण की एक मनमानी सूची को निकालते हैं कि कुछ गलत क्यों है तो आप यह निष्कर्ष निकाल सकते हैं कि वह चीज अच्छी है, वस्तुतः किसी भी चीज के लिए।
बाकूउ सिप

4
कचरा संग्रहण (जीसी) (आपका तकनीकी मुद्दा) के संबंध में, इसके बारे में कुछ खास नहीं होगा। कंस्ट्रक्टर कोड वास्तव में चलने से पहले उदाहरण मौजूद है। इस मामले में उदाहरण अभी भी उपलब्ध है, इसलिए इसे GC द्वारा दावा नहीं किया जा सकता है। यदि GC सेट होता है, तो यह उदाहरण बच जाएगा, और GC सेटिंग की प्रत्येक घटना में, ऑब्जेक्ट को सामान्य नियम के अनुसार अगली पीढ़ी में बढ़ावा दिया जाएगा। जीसी होता है या नहीं, इस पर निर्भर करता है कि (पर्याप्त) नई वस्तुएं बनाई जा रही हैं या नहीं।
जेपी स्टिग नीलसन 14

8
मैं एक कदम आगे जाऊंगा, और कहूंगा कि (सच) बुरा है, भले ही इसका उपयोग कहीं भी हो। इसका तात्पर्य है कि लूप को रोकने का कोई स्पष्ट और साफ तरीका नहीं है। आपके उदाहरण में, क्या खेल से बाहर निकलने पर लूप बंद नहीं होना चाहिए, या फोकस खो देता है?
जॉन एंडरसन

जवाबों:


250

एक निर्माता का उद्देश्य क्या है? यह एक नवनिर्मित वस्तु देता है। अनंत पाश क्या करता है? यह कभी नहीं लौटता। अगर यह बिल्कुल नहीं लौटता है तो कंस्ट्रक्टर एक नवनिर्मित वस्तु को कैसे लौटा सकता है? यह नहीं कर सकता।

एर्गो, एक अनंत लूप एक निर्माता के मौलिक अनुबंध को तोड़ता है: कुछ का निर्माण करने के लिए।


11
शायद वे बीच में एक ब्रेक के साथ (सच) डालते समय थे? जोखिम भरा, लेकिन कानूनी।
जॉन ड्वोरक

2
मैं सहमत हूं, यह सही है - कम से कम। अकादमिक दृष्टिकोण से। प्रत्येक फ़ंक्शन के लिए समान है जो कुछ देता है।
डॉक ब्राउन

61
कल्पना कीजिए कि खराब sod जो उक्त वर्ग का उप-वर्ग बनाती है ...
Newtopian

5
@JDDvorak: खैर, यह एक अलग सवाल है। ओपी ने स्पष्ट रूप से "कभी समाप्त नहीं होने" को निर्दिष्ट किया और एक घटना लूप का उल्लेख किया।
जोर्ज डब्ल्यू मित्तग

4
@ JörgWMittag अच्छी तरह से, फिर, हाँ, एक निर्माण में डाल नहीं है।
जॉन ड्वोरक

45

क्या इस तरह के दृष्टिकोण के साथ कुछ और स्पष्ट रूप से बुरा या कुटिल है?

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

इसमें से कुछ भी "बग" इस अर्थ में नहीं है कि आपका कोड काम नहीं करता है। लेकिन यह लंबे समय में कोड को बनाए रखने के लिए कठिन बनाकर (यानी, परीक्षणों को जोड़ने के लिए कठिन, पुन: उपयोग करने के लिए कठिन, डिबग करने के लिए कठिन, विस्तार करने के लिए कठिन आदि) द्वारा बड़ी माध्यमिक लागतों (संभवतः कोड लिखने की लागत के सापेक्ष) को उकसाएगा। ।)।

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

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

एक सादृश्य के साथ समाप्त करने के लिए (दूसरी प्रोग्रामिंग भाषा, यहाँ हाथ में समस्या की गणना करना है 2+2):

$sum_a = `bash -c "echo $((2+2)) 2>/dev/null"`;   # calculate
chomp $sum_a;                         # remove trailing \n
$sum_a = $sum_a + 0;                  # force it to be a number in case some non-digit characters managed to sneak in

$sum_b = 2+2;

पहले दृष्टिकोण के साथ क्या गलत है? यह समय की एक छोटी राशि के बाद 4 देता है; यह सही है। आपत्तियां (उन सभी सामान्य कारणों के साथ जो एक डेवलपर उन्हें अस्वीकार करने के लिए दे सकता है) हैं:

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

5
"जीसी कंस्ट्रक्टर चलाते समय कुछ असाधारण लॉकिंग स्थिति में हो सकता है" - क्यों? आवंटनकर्ता पहले आवंटित करता है, फिर निर्माणकर्ता को एक साधारण विधि के रूप में लॉन्च करता है। वहाँ वास्तव में इसके बारे में कुछ खास नहीं है, वहाँ है? और आबंटक को नए आवंटन (और ये OOM स्थितियों को ट्रिगर कर सकते हैं) को किसी भी तरह से निर्माण करने की अनुमति है।
जॉन ड्वोरक

1
@JDDvorak, बस इस बात को बयान करना चाहता था कि एक निर्माणकर्ता में रहते हुए "कहीं न कहीं" कुछ विशेष व्यवहार हो सकता है, लेकिन आप सही हैं, मैंने जो उदाहरण उठाया वह अवास्तविक था। हटा दिया।
AnoE

मैं वास्तव में आपके स्पष्टीकरण को पसंद करता हूं और उत्तर के रूप में दोनों उत्तरों को चिह्नित करना पसंद करूंगा (कम से कम एक upvote है)। सादृश्य अच्छा है और माध्यमिक लागतों के बारे में आपके विचार और स्पष्टीकरण का निशान यह भी है, लेकिन मैं उन्हें कोड के लिए सहायक आवश्यकताओं के रूप में मानता हूं (मेरे तर्क के रूप में)। कला की वर्तमान स्थिति कोड का परीक्षण करने के लिए है, इसलिए परीक्षण क्षमता आदि एक वास्तविक आवश्यकता है। लेकिन @ JörgWMittag के बयान fundamental contract of a constructor: to construct somethingपर हाजिर है।
शमूएल

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

4
"दुर्भाग्य से, आप नियमित रूप से प्रोग्रामर से मिलेंगे जो इस सब से पूरी तरह अनभिज्ञ हैं। यह काम करता है, बस।" इतना दुखद लेकिन इतना सच। मुझे लगता है कि मैं हम सभी के लिए बोल सकता हूं जब मैं कहता हूं कि हमारे पेशेवर जीवन में एकमात्र पर्याप्त बोझ है, ठीक है, उन लोगों को।
मोनिका से

8

आप अपने प्रश्न में इस दृष्टिकोण को नियमबद्ध करने के लिए पर्याप्त कारण देते हैं लेकिन यहाँ वास्तविक प्रश्न यह है कि "क्या इस तरह के दृष्टिकोण से कुछ अधिक स्पष्ट रूप से बुरा या भयावह है?"

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

मुझे नहीं पता कि इस तरह की स्थिति के आसपास के शब्दार्थ सी # में अच्छी तरह से परिभाषित हैं या नहीं, लेकिन मैं तर्क दूंगा कि यह कोई फर्क नहीं पड़ता क्योंकि यह कुछ ऐसा नहीं है जो अधिकांश डेवलपर्स में तल्लीन करने की कोशिश करना चाहते हैं।


मुझे लगता है कि कंस्ट्रक्टर को ऑब्जेक्ट के निर्माण के बाद चलाया जाता है, इस तरह से एक लीक भाषा में इसे सही ढंग से परिभाषित व्यवहार होना चाहिए।
मरमैन

@ मरमैन: thisकंस्ट्रक्टर में लीक होना ठीक हो सकता है - लेकिन केवल अगर आप सबसे व्युत्पन्न वर्ग के कंस्ट्रक्टर में हैं। यदि आपके पास दो वर्गों, Aऔर Bसाथ B : Aहै, अगर के निर्माता Aका रिसाव करेगा this, के सदस्यों Bको अभी भी अप्रारंभीकृत किया जाएगा (करने के लिए और आभासी विधि कॉल या डाले Bकर सकते हैं कहर बरपा कि के आधार पर)।
हॉफमैले

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

@ एमआरआरएन क्या आप सीएलआर के लिए एक निश्चित संदर्भ पा सकते हैं जो यह दिखाएगा कि मामला होना चाहिए?
जिम्मीजम्स

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

1

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

यदि आपको इस प्रकार के कोड पैटर्न को करने की आवश्यकता महसूस होती है, तो कृपया इसके बजाय कक्षा पर स्थिर विधियों का उपयोग करें।

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

यदि आप उस वस्तु का उपयोग करने का इरादा नहीं रखते हैं जिसे आप "निर्माण" कर रहे हैं, तो पहली जगह में वस्तु को तत्काल करने का क्या मतलब है? एक निर्माता में थोड़ी देर (सच) लूप होने का मतलब है कि आपने इसे पूरा करने का कभी इरादा नहीं किया है ...

C # एक बहुत ही समृद्ध वस्तु उन्मुख भाषा है, जिसमें कई अलग-अलग निर्माण और प्रतिमान हैं, जिनका पता लगाने के लिए, अपने औजारों को जानिए और उन्हें कब प्रयोग करना है, नीचे की पंक्ति:

C # में कंस्ट्रक्टर्स के भीतर विस्तारित या कभी न खत्म होने वाले तर्क को निष्पादित न करें क्योंकि ... बेहतर विकल्प हैं


1
उनके द्वारा बनाए गए अंकों से अधिक कुछ भी नहीं दिया जा रहा है और पहले 9 जवाबों में समझाया गया है
gnat

1
अरे, मुझे इसे देना था :) मुझे लगा कि यह उजागर करना महत्वपूर्ण है कि ऐसा करने के खिलाफ कोई नियम नहीं है, आपको इस तथ्य के आधार पर नहीं होना चाहिए कि सरल तरीके हैं। अधिकांश अन्य प्रतिक्रियाएं तकनीकी पर ध्यान केंद्रित करती हैं कि यह खराब क्यों है, लेकिन यह कहना मुश्किल है कि एक नए देव को बेचने के लिए "जो कहता है" लेकिन यह संकलन करता है, तो क्या मैं इसे ऐसे ही छोड़ सकता हूं "
क्रिस स्कॉलर

0

इसके बारे में कुछ भी बुरा नहीं है। हालांकि, जो महत्वपूर्ण होगा वह यह है कि आपने इस निर्माण का उपयोग करना क्यों चुना है। ऐसा करने से आपको क्या मिला?

सबसे पहले, मैं while(true)एक निर्माता में उपयोग करने के बारे में बात नहीं करने जा रहा हूँ । नहीं है बिल्कुल एक निर्माता में है कि सिंटेक्स के उपयोग के साथ कुछ भी नहीं गलत। हालांकि, "कंस्ट्रक्टर में गेम लूप शुरू करने" की अवधारणा एक है जो कुछ मुद्दों का कारण बन सकती है।

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

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

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


यदि आपके ऑब्जेक्ट का निर्माण करने के लिए गेम लूप की आवश्यकता होती है, तो कम से कम इसे फ़ैक्टरी विधि में रखें। GameTestResults testResults = runGameTests(tests, configuration);के बजाय GameTestResults testResults = new GameTestResults(tests, configuration);
user253751

@ मिनीबिस हां, यह सच है, उन मामलों को छोड़कर जहां यह अनुचित है। यदि आप एक प्रतिबिंब आधारित प्रणाली के साथ काम कर रहे हैं, जो आपके लिए अपनी वस्तु को तत्काल तैयार करती है, तो आपके पास फ़ैक्टरी विधि बनाने का विकल्प नहीं हो सकता है।
Cort Ammon

0

मेरी धारणा यह है कि कुछ अवधारणाएँ मिश्रित हो गईं और इसके परिणामस्वरूप बहुत अच्छी तरह से शब्दबद्ध प्रश्न नहीं आया।

एक वर्ग के निर्माता एक नया धागा शुरू कर सकते हैं जो कि "कभी नहीं" अंत (मैं का उपयोग करना पसंद है, हालांकि while(_KeepRunning)अधिक while(true)है क्योंकि मैं झूठा कहीं बूलियन सदस्य सेट कर सकते हैं)।

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

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


0

आपकी वस्तु मुझे कार्य शुरू करने की याद दिलाती है । टास्क ऑब्जेक्ट में एक कंस्ट्रक्टर होता है, लेकिन इसमें स्थिर फैक्ट्री विधियों का एक गुच्छा भी होता है Task.Run, जैसे: Task.Startऔर Task.Factory.StartNew

आप जो करने की कोशिश कर रहे हैं, ये बहुत समान हैं और संभावना है कि यह 'सम्मेलन' है। लोगों को लगता है कि मुख्य मुद्दा यह है कि एक निर्माता का यह उपयोग उन्हें आश्चर्यचकित करता है। @ JörgWMittag का कहना है कि यह एक मौलिक अनुबंध को तोड़ता है , जो मुझे लगता है कि Jörg बहुत हैरान है। मैं सहमत हूं और इससे जोड़ने के लिए और कुछ नहीं है।

हालांकि, मैं सुझाव देना चाहता हूं कि ओपी स्थिर कारखाना विधियों की कोशिश करता है। आश्चर्य गायब हो जाता है और यहां दांव पर कोई मौलिक अनुबंध नहीं है। लोगों को स्थिर कारखाने विधियों का उपयोग विशेष चीजें करने के लिए किया जाता है, और उन्हें तदनुसार नाम दिया जा सकता है।

आप ऐसे कंस्ट्रक्टर प्रदान कर सकते हैं जो बढ़िया दानेदार नियंत्रण की अनुमति देते हैं (जैसा कि @Brandin सुझाव देता है, कुछ ऐसा है var g = new Game {...}; g.MainLoop();, जो उन उपयोगकर्ताओं को समायोजित करता है, जो तुरंत गेम शुरू नहीं करना चाहते हैं, और शायद इसे पहले पास करना चाहते हैं। और आप var runningGame = Game.StartNew();शुरू करने के लिए कुछ लिख सकते हैं। यह तुरंत आसान है।


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

0

एक कंस्ट्रक्टर में कुछ समय (सच) लूप वास्तव में खराब क्यों है?

यह बिल्कुल भी बुरा नहीं है।

क्यों (या यह बिल्कुल भी है?) एक वर्ग के एक निर्माता को कभी न खत्म होने वाले लूप (यानी गेम लूप) शुरू करने के लिए खराब डिजाइन के रूप में माना जाता है?

आप कभी ऐसा क्यों करना चाहेंगे? गंभीरता से। उस वर्ग का एक ही कार्य है: निर्माणकर्ता। यदि आप चाहते हैं कि सभी एक ही कार्य है, इसलिए हमारे पास कार्य हैं, न कि निर्माता।

आपने खुद इसके खिलाफ कुछ स्पष्ट कारणों का उल्लेख किया है, लेकिन आपने सबसे बड़ी एक को छोड़ दिया है:

एक ही चीज़ को प्राप्त करने के लिए बेहतर और सरल विकल्प हैं।

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


-1

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

अप्रत्यक्ष रूप से सभी तर्क को कंस्ट्रक्टर में डालकर, आप अपने ऊपर इस तरह का अधिक बोझ डालते हैं। इससे पता चलता है कि आपने इनिशियलाइज़ेशन के बीच के अंतर को डिज़ाइन नहीं किया है और पर्याप्त रूप से उपयोग करते हैं।


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