2010-11-17 7 views
23

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

class SingletonExample 
{ 
    private SingletonExample mInstance; 
    //other members... 
    private SingletonExample() 
    { 

    } 
    public SingletonExample Instance 
    { 
     get 
     { 
       if (mInstance == null) 
       { 
        throw new Exception("Object not created"); 
       } 
       return mInstance; 
     } 
    } 

    public void Create(string arg1, string arg2) 
    { 
     mInstance = new SingletonExample(); 
     mInstance.Arg1 = arg1; 
     mInstance.ObjectCaller = new ObjectCaller(arg2); 
     //etc... basically, create object... 
    } 
} 

उदाहरण 'देर' बनाई गई है, जिसका अर्थ है मैं अनुप्रयोग स्टार्टअप पर जरूरत सभी तर्क नहीं है।

आम तौर पर मुझे विधि कॉल के क्रम को मजबूर करना पसंद नहीं है, लेकिन मुझे यहां एक और तरीका नहीं दिख रहा है। आईओसी या तो इसे हल होगा नहीं, क्योंकि मैं कहाँ कंटेनर में रजिस्टर कर सकते हैं, मैं भी कॉल कर सकते हैं बनाएँ() ...

आप इस एक ठीक परिदृश्य पर विचार करते हैं? क्या आपके पास कुछ और विचार है?

संपादित: मुझे पता है कि मैं क्या एक उदाहरण के रूप में लिखा था कि यह सुरक्षित थ्रेड नहीं है, धागा सुरक्षित प्रश्न

+0

है कि * * एक सिंगलटन नहीं। पारस्परिक बहिष्कार कहां है? (यानी 'ताला')। इसके अलावा उदाहरण के लिए आपका 'गेटर' उदाहरण बनाना चाहिए, सीटीओ नहीं - यह पूरा बिंदु है। – RPM1984

+0

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

+1

यह सिंगलटन ठीक है, मुझे विश्वास है :) 'getter' उदाहरण नहीं बना सकते क्योंकि यह तर्क नहीं है - यह हो सकता था, लेकिन यह इसे इस तरह लिखने के लिए सिर्फ अधिक सुविधाजनक है। और, एक बार प्राप्त तर्क, परिवर्तन नहीं करते हैं। – veljkoz

उत्तर

18

एक सिंगलटन मेरे लिए गड़बड़ बदबू आ रही है।

Whateva के जवाब और निम्नलिखित कोड पर विचार करें:

Singleton x = Singleton.getInstance("hello", "world"); 
Singleton y = Singleton.getInstance("foo", "bar"); 

जाहिर है, एक्स == एक्स के निर्माण मानकों के साथ y और y काम करता है, जबकि y के निर्माण मानकों बस अनदेखी कर रहे हैं। परिणाम शायद कम से कम भ्रमित कर रहे हैं।

यदि आप सच में, सच गिर गया है कि आपने इसे क्या करना है, इस तरह यह कार्य करें:

class SingletonExample 
{ 
    private static SingletonExample mInstance; 
    //other members... 
    private SingletonExample() 
    { // never used 
     throw new Exception("WTF, who called this constructor?!?"); 
    } 
    private SingletonExample(string arg1, string arg2) 
    { 
     mInstance.Arg1 = arg1; 
     mInstance.ObjectCaller = new ObjectCaller(arg2); 
     //etc... basically, create object...  
    } 
    public static SingletonExample Instance 
    { 
     get 
     { 
       if (mInstance == null) 
       { 
        throw new Exception("Object not created"); 
       } 
       return mInstance; 
     } 
    } 

    public static void Create(string arg1, string arg2) 
    { 
     if (mInstance != null) 
     { 
      throw new Exception("Object already created"); 
     } 
     mInstance = new SingletonExample(arg1, arg2);    
    } 
} 

एक बहु सूत्रण वातावरण में, तुल्यकालन जोड़ने दौड़ की स्थिति से बचने के लिए।

+6

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

+6

मासिमिलीनो, मेरे समाधान में आप बिल्कुल एक बार कॉल कर सकते हैं। और मुझे लगता है कि मेरी टेक्स्टिंग यह स्पष्ट करती है कि मैं पैरामीट्रिक सिंगलटन के विचार से वास्तव में शौकीन नहीं हूं। –

+0

@ मैसिमिलीनो पेलुसो - अब ** ** ** एक उपयोगी अवलोकन है - एक कारखाना ... जो मैं बाद में हूं वह वास्तव में सिंगलटन/फैक्ट्री का मिश्रण है, जो वास्तव में आईओसी को उबालता है ... वैसे भी, मुझे लगता है कि मेरे पास है मेरा जवाब अब धन्यवाद – veljkoz

0

मैं वास्तव में अपने कोड में एक सिंगलटन नहीं देख सकते हैं का हिस्सा नहीं है। एक स्थिर, पैरामीटरकृत इंस्टेंस विधि का उपयोग करें जो सिंगलटन लौटाता है और इसे पहले बनाता है अगर इसे पहले उपयोग नहीं किया गया था।

4

बेहतर जवाब: ISingleton (युक्त जो कुछ भी कार्रवाई आप इसे करने के लिए क्या चाहते हैं)

  • और अपने प्रकार::

    1. एक अंतरफलक बनाएं Singleton : ISingleton

    2. आप यह मानते हुए एक के लिए उपयोग किया यूनिटीकॉन्टेनर:

    IUnityContainer _singletonContainer = new UnityContainer(); // or whatever code to initialize the container

    1. जब आप अपने प्रकार का उपयोग करें (आप डि के लिए एकता का उपयोग कर रहे कल्पना करते हुए) बनाने के लिए तैयार हैं:

    _singletonContainer.RegisterType(typeof(ISingleton), new Singleton(params));

    1. तुम सिर्फ सिंगलटन हड़पने के लिए चाहते हैं का उपयोग करें:

    var localSingletonVar = _singletonContainer.Resolve<ISingleton>();

    नोट: यदि कंटेनर के पास ISingleton इंटरफ़ेस के लिए कोई प्रकार पंजीकृत नहीं है, तो इसे या तो अपवाद फेंकना चाहिए, या तो शून्य वापस कर देना चाहिए।

    ओल्ड उत्तर:

    public class Singleton 
    { 
    
        private static Singleton instance = null; 
    
        private Singleton(String arg1, String arg2) 
        { 
        } 
    
        public static Singleton getInstance(String arg1, String arg2) 
        { 
         if (instance != null) 
         { 
          throw new InvalidOperationException("Singleton already created - use getinstance()"); 
         } 
         instance = new Singleton(arg1, arg2); 
         return instance; 
        } 
    
        public static Singleton getInstance() 
        { 
         if (instance == null) 
          throw new InvalidOperationException("Singleton not created - use GetInstance(arg1, arg2)"); 
         return instance; 
        } 
    } 
    

    मैं कुछ इसी तरह के साथ जाना चाहते हैं, तो आपके डि कंटेनर गैर पंजीकृत प्रकार पर अपवाद फेंकने का समर्थन करता है, मैं होगा (आप की जाँच करने के लिए यदि उदाहरण भी बनाया गया था की जरूरत सकता है), या उसके साथ जाओ

    ध्यानार्थ: गैर धागा सुरक्षित कोड :) मानकों के साथ

  • +0

    आप कक्षा का उदाहरण कहां बनाते हैं ??? –

    +0

    टाइपो –

    22

    सिंगलटन बदसूरत है लेकिन उपयोगकर्ता Whateva के बाद से अपने ही कोड को दूर करने के परेशान नहीं किया जा सकता है ...

    public class Singleton 
    { 
        private static Singleton _instance = null; 
    
        private static Object _mutex = new Object(); 
    
        private Singleton(object arg1, object arg2) 
        { 
         // whatever 
        } 
    
        public static Singleton GetInstance(object arg1, object arg2) 
        { 
         if (_instance == null) 
         { 
          lock (_mutex) // now I can claim some form of thread safety... 
          { 
           if (_instance == null) 
           { 
            _instance = new Singleton(arg1, arg2); 
           } 
          } 
         } 
    
         return _instance; 
        } 
    } 
    

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

    संपादित करें: प्रकार, प्रासंगिक उपयोग आप क्या चाहते हैं नहीं कर रहे हैं object सिर्फ सुविधा के लिए यहां इस्तेमाल किया जाता है।

    +0

    अब, यह एक सिंगलटन है, न कि मैं उन्हें स्पष्ट रूप से उपयोग करता हूं (मैं उन्हें डीआई करने देता हूं, और केवल लॉगिंग जैसी चीजों के लिए)। +1 – RPM1984

    +0

    मैं आगे बढ़ने वाला हूं और मानता हूं कि व्हाटवा ने एक कार्यात्मक सही उत्तर को कम करने का फैसला किया है। टीम चलो। – annakata

    +0

    नहीं, उसने नहीं किया (उसकी प्रोफ़ाइल देखें)। वैसे भी, सिंगलटन की इस बात ने मुझे नींद आ गई है, मैं बिस्तर पर उतर गया हूं। :) – RPM1984

    2

    डबल लॉक सिंगलटन annakata द्वारा प्रदान समाधान सभी प्लेटफार्मों पर हर काम नहीं करेगा। इस दृष्टिकोण में एक दोष है जो अच्छी तरह से प्रलेखित है। इस दृष्टिकोण का उपयोग न करें या आप समस्याओं के साथ खत्म हो जाएंगे।

    इस समस्या को हल करने का एकमात्र तरीका अस्थिर कीवर्ड का उपयोग करना है उदा।

    private static volatile Singleton m_instance = null; 
    

    यह केवल धागा सुरक्षित तरीका है।

    2

    आप नेट 4 (या अधिक) का उपयोग कर रहे हैं, तो आप System.Lazy प्रकार का उपयोग कर सकते हैं। यह आपके लिए थ्रेड सुरक्षा समस्या का ख्याल रखेगा और इसे आलसी करेगा ताकि आप अनावश्यक रूप से उदाहरण नहीं बना सकें। इस तरह कोड छोटा और साफ है।

    public sealed class Singleton 
    { 
        private static readonly Lazy<Singleton> lazy = 
         new Lazy<Singleton>(() => new Singleton(),LazyThreadSafetyMode.ExecutionAndPublication); 
    
        private Singleton() { } 
    
        public static Singleton Instance { get { return lazy.Value; } } 
    }