क्या किसी निर्माता में किसी वस्तु के काम करने का कोई कारण है?


49

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

जैसे-जैसे हमारी कंपनी बढ़ी है, हमने अपने विकास को घर में ले जाने की कोशिश की है। यह विशेष परियोजना मेरी गोद में उतरी है इसलिए मैं इस पर जा रहा हूं, इसे साफ करना, परीक्षण जोड़ना, आदि।

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

उदाहरण के लिए, (कोड जावा में है, अगर यह मायने रखता है, लेकिन मुझे उम्मीद है कि यह अधिक सामान्य प्रश्न होगा):

public class Foo {
  private int bar;
  private String baz;

  public Foo(File f) {
    execute(f);
  }

  private void execute(File f) {
     // FTP the file to some hardcoded location, 
     // or parse the file and commit to the database, or whatever
  }
}

यदि आप सोच रहे हैं, तो इस प्रकार के कोड को अक्सर निम्नलिखित तरीके से कहा जाता है:

for(File f : someListOfFiles) {
   new Foo(f);
}

अब, मुझे बहुत पहले सिखाया गया था कि एक लूप में तात्कालिक वस्तुएं आमतौर पर एक बुरा विचार है, और यह कि कंस्ट्रक्टरों को कम से कम काम करना चाहिए। इस कोड को देखकर ऐसा लगता है कि कंस्ट्रक्टर को गिराना और executeसार्वजनिक स्थैतिक विधि बनाना बेहतर होगा ।

मैंने ठेकेदार से पूछा कि यह इस तरह क्यों किया गया था, और मुझे जो प्रतिक्रिया मिली वह थी "यदि आप चाहें तो हम इसे बदल सकते हैं"। जो वास्तव में मददगार नहीं था।

वैसे भी, किसी भी प्रोग्रामिंग भाषा में ऐसा करने का कभी कोई कारण है, या यह डेली डब्ल्यूटीएफ के लिए एक और सबमिशन है?


18
मुझे ऐसा लगता है जैसे यह डेवलपर्स द्वारा लिखा गया था, जिनके बारे में जानते हैं public static void main(string[] args)और जिन्होंने वस्तुओं के बारे में सुना है, फिर उन्हें एक साथ मैश करने की कोशिश की।
एंडी हंट

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

4
संबंधित प्रश्न: किसी वर्ग के मुख्य कार्य को उसके निर्माण में करने में कोई समस्या? । यह थोड़ा अलग है, हालांकि, क्योंकि निर्मित उदाहरण बाद में उपयोग किया जाता है।
15


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

जवाबों:


60

ठीक है, सूची में नीचे जा रहा है:

मुझे बहुत पहले सिखाया गया था कि एक लूप में तात्कालिक वस्तुएं आमतौर पर एक बुरा विचार है

मैंने जो भी भाषाएं इस्तेमाल की हैं उनमें नहीं।

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

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

कंस्ट्रक्टरों को कम से कम काम करना चाहिए

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

क्या कभी किसी प्रोग्रामिंग भाषा में ऐसा कुछ करने का कारण है, या यह डेली डब्ल्यूटीएफ के लिए एक और सबमिशन है?

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

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

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

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

3
लघु संस्करण: जैसे वे एक समारोह थे वस्तु तात्कालिकता का उपयोग न करें।
एरिक रेपेने

27

मेरे लिए, यह एक आश्चर्य की बात है जब आपको किसी ऑब्जेक्ट को कंस्ट्रक्टर में बहुत अधिक काम करने का मौका मिलता है, तो बस उस पर मैं इसके खिलाफ सुझाऊंगा (कम से कम आश्चर्य का सिद्धांत)।

एक अच्छे उदाहरण पर एक प्रयास :

मुझे यकीन नहीं है कि यह उपयोग एक विरोधी पैटर्न है, लेकिन सी # में मैंने कोड देखा है जो (कुछ हद तक बना उदाहरण) की तर्ज पर था:

using (ImpersonationContext administrativeContext = new ImpersonationContext(ADMIN_USER))
{
    // Perform actions here under the administrator's security context
}
// We're back to "normal" privileges here

इस मामले में, ImpersonationContextक्लास अपना सारा काम कंस्ट्रक्टर और डिस्पोज़ विधि में करता है। यह C # usingस्टेटमेंट का लाभ उठाता है , जो C # डेवलपर्स द्वारा काफी अच्छी तरह से समझा जाता है, और इस तरह गारंटी देता है कि कंस्ट्रक्टर में जो सेटअप होता है, उसे एक बार usingस्टेटमेंट के बाहर रहने पर भी रोल किया जाता है , भले ही कोई अपवाद हो। यह संभवत: मैंने इसके लिए सबसे अच्छा उपयोग किया है (यानी कंस्ट्रक्टर में "काम"), हालांकि मुझे अभी भी यकीन नहीं है कि मैं इसे "अच्छा" मानूंगा। इस मामले में, यह काफी आत्म-व्याख्यात्मक, कार्यात्मक और रसीला है।

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

आपके उदाहरण पर टिप्पणियाँ:

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

मैं उद्धरण खोजने के लिए संघर्ष कर रहा हूं, लेकिन ग्रैडी बोच की पुस्तक "ऑब्जेक्ट सॉल्यूशंस" में सी + + की संक्रमण करने वाली सी डेवलपर्स की टीम के बारे में एक किस्सा है। जाहिरा तौर पर वे प्रशिक्षण के माध्यम से थे, और प्रबंधन द्वारा कहा गया था कि उन्हें पूरी तरह से "वस्तु उन्मुख" चीजें करनी थीं। यह पता लगाने के लिए कि क्या गलत है, लेखक ने एक कोड मीट्रिक टूल का उपयोग किया, और पाया कि प्रति वर्ग विधियों की औसत संख्या बिल्कुल 1 थी, और "डू इट" वाक्यांश के रूपांतर थे। मुझे कहना होगा, मैंने पहले कभी इस विशेष समस्या का सामना नहीं किया है, लेकिन जाहिर है यह लोगों का एक लक्षण हो सकता है कि ऑब्जेक्ट ओरिएंटेड कोड बनाने के लिए मजबूर किया जाए, वास्तव में यह समझने के बिना कि ऐसा कैसे करना है, और क्यों।


1
आपका अच्छा उदाहरण है संसाधन आवंटन का एक उदाहरण है इनिशियलाइज़ेशन । यह C ++ में एक अनुशंसित पैटर्न है क्योंकि इससे अपवाद-सुरक्षित कोड लिखना बहुत आसान हो जाता है। मैं नहीं जानता कि क्या यह C # पर ले जाता है, हालांकि। (इस मामले में "संसाधन" आवंटित किया जाना प्रशासनिक विशेषाधिकार है।)
zwol

@Zack मैंने उन शर्तों के बारे में कभी नहीं सोचा है, भले ही मैं C ++ में RAII के बारे में जानता हूं। C # दुनिया में, इसे डिस्पोजेबल पैटर्न के रूप में संदर्भित किया जाता है, और यह किसी भी चीज के लिए बहुत अधिक अनुशंसित है, जो (आमतौर पर अप्रबंधित) संसाधनों को अपने जीवनकाल के बाद मुक्त करने के लिए है। इस उदाहरण के लिए मुख्य अंतर यह है कि आप आम तौर पर कंस्ट्रक्टर में महंगे ऑपरेटर नहीं करते हैं । उदाहरण के लिए एक SqlConnection की ओपन () विधि को अभी भी निर्माता के बाद बुलाया जाना चाहिए।
डैनियल बी

14

नहीं।

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

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


7

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

मुझे लगता है कि यहाँ एक अजीब बात यह है कि एक निर्माता में साइड इफेक्ट्स के साथ कोड डालना है। किसी ऑब्जेक्ट का निर्माण करना और गुणों या तरीकों तक पहुंच के बिना इसे फेंकना अजीब लगता है (लेकिन कम से कम इस मामले में यह बहुत स्पष्ट है कि कुछ और चल रहा है)।

यह बेहतर होगा यदि फ़ंक्शन को एक सार्वजनिक विधि में स्थानांतरित किया गया था, और फिर कक्षा को इंजेक्ट करने का एक उदाहरण है, तो लूप कॉल विधि को बार-बार कॉल करें।


4

क्या किसी निर्माता में किसी वस्तु के काम करने का कोई कारण है?

नहीं।

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

कोई इन दिशानिर्देशों पर यथोचित सवाल कर सकता है और कह सकता है, "लेकिन मैं इन नियमों का पालन नहीं करता, और मेरा कोड ठीक काम करता है!" उस तक, मैं जवाब देता हूं, "ठीक है कि यह सच हो सकता है, जब तक कि यह न हो।"

  • एक निर्माणकर्ता के अंदर अपवाद और त्रुटियां बहुत अप्रत्याशित हैं। जब तक उन्हें ऐसा करने के लिए नहीं कहा जाता है, भविष्य के प्रोग्रामर इन कंस्ट्रक्टर कॉल्स को रक्षात्मक कोड के साथ घेरने के लिए इच्छुक नहीं होंगे।
  • यदि कुछ भी उत्पादन में विफल रहता है, तो उत्पन्न स्टैक ट्रेस को पार्स करना मुश्किल हो सकता है। स्टैक ट्रेस का शीर्ष, कंस्ट्रक्टर कॉल को इंगित कर सकता है, लेकिन कंस्ट्रक्टर में बहुत सी चीजें होती हैं, और यह वास्तविक LOC को इंगित नहीं कर सकता है जो विफल रहा।
    • मैंने कई .NET स्टैक के निशान देखे हैं जहाँ यह मामला था।

1
"जब तक उन्हें ऐसा करने के लिए नहीं कहा जाता है, भविष्य के प्रोग्रामर इन कंस्ट्रक्टर कॉल्स को रक्षात्मक कोड के साथ घेरने के लिए इच्छुक नहीं होंगे।" - अच्छी बात।
ग्राहम

2

मुझे ऐसा लगता है कि ऐसा करने वाला व्यक्ति जावा की सीमा के आसपास हैक करने की कोशिश कर रहा था जो प्रथम श्रेणी के नागरिकों के रूप में कार्यों को पारित करने की अनुमति नहीं देता है। जब भी आपको कोई फंक्शन पास करना होता है, तो आपको क्लास के अंदर applyया उसके जैसे तरीके से लपेटना होता है ।

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

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


3
मुझे पूरा यकीन है कि इस विशेष प्रोग्रामर ने कभी भी 'कार्यात्मक प्रोग्रामिंग' वाक्यांश नहीं सुना है।
केन

मुझे नहीं लगता कि प्रोग्रामर क्लोजर एब्सट्रैक्ट बनाने का प्रयास कर रहा था। जावा समतुल्य को एक सार विधि (संभव के लिए योजना) बहुरूपता की आवश्यकता होगी। यहाँ इसका सबूत नहीं है।
केविन ए। नौडे

1

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


1

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

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

उपयोगिता वर्ग के साथ भी, अधिकांश लोग नेस्टेड स्टैटिक क्लासेस के लिए नहीं सोचेंगे (और यह संभव नहीं हो सकता है या तो भाषा के आधार पर)।

मूल रूप से यह व्यवहार को बाकी व्यवस्था से अलग करने का एक अपेक्षाकृत समझदार तरीका है, जो कि भाषा द्वारा अनुमत है, जबकि अभी भी आपको भाषा का अधिक से अधिक लाभ उठाने की अनुमति है।

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


1

ऐसी भाषाओं में पैटर्न सामान्य हैं जहाँ फ़ंक्शंस और कक्षाएं बहुत अधिक समान हैं, जैसे पायथन, जहाँ कोई मूल रूप से बहुत सारे साइड-इफ़ेक्ट्स के साथ या कई नामांकित ऑब्जेक्ट्स के साथ कार्य करने के लिए मूल रूप से एक ऑब्जेक्ट का उपयोग करता है।

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

var parser = XMLParser()
var x = parser.parse(string)
string a = x.LookupTag(s)

वास्तव में से बेहतर नहीं है

 var x = ParsedXML(string)
 string a = x.LookupTag(s)

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

x.UpdateView(v)

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

var x = new ComputeStatistics(inputFile)
int max = x.MaxOptions;
int mean = x.AverageOption;
int sd = x.StandardDeviation;
int k = x.Kurtosis;
...

तो संयुक्त पायथन / सी # प्रोग्रामर के रूप में, यह सब मुझे अजीब नहीं लगता।


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

1

एक मामला ध्यान में आता है जहां निर्माणकर्ता / विध्वंसक सभी काम करता है:

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

मैंने यह भी लिखा है कि एक रनटाइम लाइब्रेरी बग को पैच करने के लिए एक कंस्ट्रक्टर-केवल बिट कोड की क्या राशि है। (वास्तव में कोड को ठीक करने से अन्य समस्याएं हो सकती थीं।) कोई विध्वंसक नहीं था क्योंकि पैच को पूर्ववत करने की कोई आवश्यकता नहीं थी।


-1

मैं एंडीबर्श से सहमत हूं। ऐसा लगता है कि ज्ञान के मुद्दे में कुछ कमी है।

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


-4

"मुझे बहुत पहले सिखाया गया था कि एक लूप में तात्कालिक वस्तुएं आमतौर पर एक बुरा विचार है"

हां, हो सकता है कि आप याद कर रहे हों कि हमें स्ट्रेंजबर्स्ट की आवश्यकता क्यों है।

जावा के दो स्कूल हैं।

बिल्डर को पहले एक द्वारा पदोन्नत किया गया था , जो हमें पुन: उपयोग करना सिखाता है (क्योंकि दक्षता के लिए साझाकरण = पहचान)। हालाँकि, 2000 की शुरुआत में मैंने यह पढ़ना शुरू किया कि जावा में ऑब्जेक्ट बनाना इतना सस्ता है (जैसा कि C ++ के विपरीत) और GC इतना कुशल है कि पुन: उपयोग करना बेकार है और केवल एक चीज जो प्रोग्रामर की उत्पादकता है। उत्पादकता के लिए, उसे प्रबंधनीय कोड लिखना चाहिए, जिसका अर्थ है मॉडर्नाइजेशन (स्कोप को कम करना)। इसलिए,

ये गलत है

byte[] array = new byte[kilos or megas]
for_loop:
  use(array)

यह अच्छा है।

for_loop:
  byte[] array = new byte[kilos or megas]
  use(array)

मैंने यह सवाल तब पूछा, जब forum.java.sun मौजूद था, और लोग इस बात से सहमत थे कि वे ऐरे को यथासंभव संकीर्ण घोषित करना पसंद करेंगे।

आधुनिक जावा प्रोग्रामर कभी भी एक नए वर्ग की घोषणा करने या एक वस्तु बनाने में संकोच नहीं करता है। उसे ऐसा करने के लिए प्रोत्साहित किया जाता है। जावा ऐसा करने के लिए सभी कारण देता है, इस विचार के साथ कि "सब कुछ एक वस्तु है" और सस्ते निर्माण।

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

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

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

"अपने निर्माता में कुछ भी मत करो। यह केवल आरंभीकरण के लिए है"

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


3
स्पष्टीकरण अच्छी तरह से संरचित नहीं है और इसका पालन करना कठिन है। आप बस सभी जगह पर दावे के साथ जा सकते हैं जिनका संदर्भ से कोई संबंध नहीं है।
न्यू अलेक्जेंड्रिया

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