Static Create Method - कंस्ट्रक्टरों के साथ पेशेवरों और विपक्षों की तुलना में


11

कंस्ट्रक्टरों पर स्थिर ऑब्जेक्ट निर्माण विधियों के पेशेवरों और विपक्ष क्या हैं?

class Foo {
  private Foo(object arg) { }

  public static Foo Create(object arg) {
    if (!ValidateParam(arg)) { return null; }
    return new Foo(arg);
  }
}

कुछ ऐसा जो मैं सोच सकता हूँ:

पेशेवरों:

  • अपवाद फेंकने के बजाय अशक्त लौटें (इसे नाम दें TryCreate)। यह क्लाइंट की तरफ कोड को और अधिक स्पष्ट और स्वच्छ बना सकता है। ग्राहक शायद ही कभी निर्माणकर्ता से असफल होने की उम्मीद करते हैं।
  • स्पष्ट शब्दार्थ के साथ विभिन्न प्रकार की वस्तुएँ बनाएँ, जैसे CreatFromName(String name)औरCreateFromCsvLine(String csvLine)
  • यदि आवश्यक हो, या एक व्युत्पन्न कार्यान्वयन एक कैश्ड वस्तु वापस कर सकते हैं।

विपक्ष:

  • कम खोज योग्य, स्किम कोड को और अधिक कठिन।
  • कुछ पैटर्न, जैसे क्रमांकन या प्रतिबिंब अधिक कठिन हैं (उदाहरण के लिए Activator<Foo>.CreateInstance())

1
यह धीमा है। आपको वैसे भी अशक्त संदर्भ को संभालना होगा।
अमीर रज़ाई

1
@Amir हैंडलिंग नल ( Foo x = Foo.TryCreate(); if (x == null) { ... }) है। एक ctor अपवाद को हैंडल करना ( Foo x; try { x = new Foo(); } catch (SomeException e) { ... }) है। सामान्य तरीके से कॉल करते समय, मैं त्रुटि कोड के अपवादों को प्राथमिकता देता हूं, लेकिन ऑब्जेक्ट निर्माण के साथ, TryCreateक्लीनर लगता है।
dbkk

क्या आप अपने सत्यापन में किसी प्रकार की जाँच करेंगे?
अमीर रज़ाई

दूसरे प्रो के संबंध में, "स्पष्ट शब्दार्थ के साथ विभिन्न प्रकार की वस्तुएं बनाएं, जैसे CreatFromName (स्ट्रिंग नाम) और CreateFromCsvLine (स्ट्रिंग csvLine)", आप विधि नामों के माध्यम से व्यक्त आवश्यकताओं के बजाय बनाने Nameऔर CsvLineटाइप करने के लिए बेहतर हो सकते हैं । यह आपको Create को ओवरलोड करने की अनुमति देगा। दोनों के लिए तार का उपयोग "आदिम जुनून" माना जा सकता है (यह मानते हुए कि आपने प्रदर्शन के कारणों के लिए यह विकल्प नहीं बनाया है)। यह पता लगाने के लिए एक मजेदार तरीके से ऑब्जेक्ट कैलिसथेनिक्स की जाँच करें।
बेंटाय्लोरुक

जवाबों:


7

स्थैतिक ' रचनाकारों ' के साथ सबसे बड़ी कमी शायद विरासत को सीमित करना है। यदि आप या आपके पुस्तकालय का उपयोगकर्ता आपके से एक वर्ग प्राप्त करता है Foo, तो Foo::Create()बहुत अधिक बेकार हो जाता है। वहाँ परिभाषित सभी तर्क को विरासत में फिर से लिखना होगा Create()

मैं एक समझौता सुझाता हूं: एक निर्माणकर्ता को तुच्छ वस्तु आरंभीकरण तर्क के साथ परिभाषित करें जो कभी विफल / फेंकता नहीं है, फिर निर्माता, को कैशिंग, वैकल्पिक निर्माण आदि के साथ परिभाषित करें, जो व्युत्पन्न होने की संभावना को छोड़ देता है और आपको किसी दिए गए वर्ग के लिए रचनाकार होने से लाभ होता है। ।


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

7

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

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