एक "प्रारंभ", "रन" या "निष्पादित" विधि एक अच्छा अभ्यास है?


30

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

सामान्य ऑब्जेक्ट निर्माण के बजाय एक स्टार्ट विधि का उपयोग करना कब उचित है?

मुझे कंस्ट्रक्टर का उपयोग कब करना चाहिए?

संपादित करें: मुझे नहीं लगता कि यह प्रासंगिक है लेकिन प्रोग्रामिंग भाषा C # है, यह समान रूप से जावा या C ++ पर लागू हो सकती है


3
क्या आप थोड़ा और संदर्भ जोड़ सकते हैं? भाषा? थ्रेड बनाम एकल धागा? startऔर निर्माता के बीच अंतर ? आदि ...

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

2
@DaveHillier उदाहरण के लिए, पर्ल में यह मानक अभ्यास (और एक अच्छा) है जो फ़ंक्शन के initबाहर किसी प्रकार का एक तरीका है new- perldoc.perl.org/perlobj.html । एक भाषा के मुहावरे वहां पर अच्छी तरह से काम कर सकते हैं, अन्य भाषाओं में नहीं।

1
Startसामान्य एपीआई में विधियों वाले वर्गों के उदाहरणों में थ्रेड्स और स्टॉपवॉच शामिल हैं।
लुइसबुलल

1
मुझे उन लोगों में गिनें जिन्हें समझने के लिए कोड नमूने की आवश्यकता है कि आप वास्तव में क्या पूछ रहे हैं।
user16764

जवाबों:


44

एक Start()विधि (जैसे Run(), Execute()या कुछ भी समान) उपयुक्त है जब ऑब्जेक्ट के निर्माण की लागत कम है, लेकिन इसका उपयोग करने की लागत अधिक है। उदाहरण के लिए: एक वर्ग जो एक सर्वोत्तम पथ-अनुकूलन एल्गोरिथ्म को एन्क्रिप्ट करता है। इसे मानकों के एक सेट ( Xवर्गों द्वारा Yवर्गों, suchandsuch मूल्यांकन पद्धति के साथ) के साथ सेट करना मामूली है, लेकिन इसे निष्पादित करने में थोड़ा समय लग सकता है। यदि आप इनमें से 20 ऑब्जेक्ट बनाना चाहते हैं, तो आप निष्पादन में देरी करना चाहते हैं, जब तक कि उनमें से सभी का निर्माण नहीं हो जाता है - यह आपको उदाहरण के लिए, उन्हें आसान समानांतर करने देता है।

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

यह मानता है, निश्चित रूप से, यह Start()वस्तु पर उपयोगी विधि है, और एक Initialize()विधि के बराबर नहीं है । यदि यह अधिक पैरामीटर सेट करने का सिर्फ एक अतिरिक्त तरीका है, तो यह मौजूद नहीं होना चाहिए।


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

50

कोड कम्प्लीट (और कई अन्य सॉफ्टवेयर इंजीनियरिंग संसाधन) वास्तविक दुनिया की वस्तुओं के लिए आपकी कक्षाओं के मिलान पर जोर देते हैं। मेरा मानना ​​है कि इसका मूल कारण यह है कि यह इस बात की अधिक संभावना है कि आपके पास एक अमूर्त विचार को हैक करने के बजाय यह है कि आप इसे लागू कर रहे हैं या नहीं।

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


16
एक अच्छा सादृश्य। यह ध्यान देने योग्य है कि Start()या तो ऑन / ऑफ स्विच (जैसे लाइटस्विच) के अनुरूप हो सकता है Stop(), जो तब होना चाहिए , या एक पुश-बटन (जैसे कॉपी मशीन पर प्रिंट बटन) जहां यह बंद हो जाता है और तब तक चलता है।
बोबन्सन

3
+1 ने कहा और P.SE में आपका स्वागत है, इस तरह के उत्तर एक शानदार शुरुआत है।
जिमी हॉफ

14

आप आलसी आरंभीकरण का उपयोग कर सकते हैं

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

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

महंगी आरंभीकरण में देरी जब तक यह पहली जरूरत है ..

उदाहरण:

public class FooClass{

    private ExpensiveResource resource;
    private CheapResource cheap;

    public  FooClass(String someParameter){
        // constructor: initialize CheapResource cheap 
            // but NOT ExpensiveResource resource
    }

    public ExpensiveResource getExpensiveResource(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource
    }

    public String getExpensiveResourceName(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource.getName();
    }   

    public CheapResource getCheapResource(){
        return this.cheap;
    }

    private initializeExpensiveResource(){
        // do expensive initialization of field "resource"
    }

}

public class Test{
    public static void main (String args[]){

        FooClass foo = new FooClass("some string");
        CheapResource cr = foo.getCheapResource();
        String s = foo.getExpensiveResourceName(); 
          // just now is the expensive resource initialized

    }
}

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

@DanAlbert आप सही हैं यह वह नहीं है जो मैं पूछ रहा था, लेकिन अभी भी दिलचस्प है
डेव हिलियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.