design patterns - स्थिर वर्ग और सिंगलटन पैटर्न के बीच अंतर?




design-patterns static (20)

  1. धीरे लोड हो रहा है
  2. इंटरफेस का समर्थन, ताकि अलग कार्यान्वयन प्रदान किया जा सके
  3. व्युत्पन्न प्रकार को वापस करने की क्षमता (lazyloading और इंटरफ़ेस कार्यान्वयन के संयोजन के रूप में)

एक स्थिर वर्ग और एक सिंगलटन पैटर्न के बीच क्या असली (यानी व्यावहारिक) अंतर मौजूद है?

दोनों को तत्काल बिना बुलाया जा सकता है, दोनों केवल एक "इंस्टेंस" प्रदान करते हैं और उनमें से कोई भी थ्रेड-सुरक्षित नहीं है। क्या कोई और अंतर है?


  1. सिंगलटन ऑब्जेक्ट्स हीप में संग्रहीत होते हैं, लेकिन स्थैतिक वस्तुएं ढेर में संग्रहित होती हैं।
  2. हम क्लोन कर सकते हैं (यदि डिजाइनर ने इसे अस्वीकार नहीं किया है) सिंगलटन ऑब्जेक्ट, लेकिन हम स्थिर वर्ग ऑब्जेक्ट को क्लोन नहीं कर सकते हैं।
  3. सिंगलटन कक्षाएं ओओपी (वस्तु उन्मुख सिद्धांतों) का पालन करती हैं, स्थैतिक कक्षाएं नहीं होती हैं।
  4. हम सिंगलटन कक्षा के साथ एक interface को कार्यान्वित कर सकते हैं, लेकिन एक वर्ग की स्थैतिक विधियां (या उदाहरण के लिए सी # static class ) नहीं कर सकती हैं।

आप क्या कहते हैं कि या तो सिंगलटन या स्थैतिक विधि थ्रेड-सुरक्षित नहीं है? आम तौर पर दोनों को थ्रेड-सुरक्षित होने के लिए लागू किया जाना चाहिए

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


एक उल्लेखनीय अंतर अलग-अलग तत्काल है जो सिंगलेट्स के साथ आता है।

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


एक स्थैतिक वर्ग वह होता है जिसमें केवल स्थैतिक विधियां होती हैं, जिसके लिए एक बेहतर शब्द "कार्य" होगा। एक स्थिर वर्ग में अवशोषित डिजाइन शैली पूरी तरह से प्रक्रियात्मक है।

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


ए। सीरियलाइजेशन - स्टेटिक सदस्य कक्षा से संबंधित हैं और इसलिए धारावाहिक नहीं किया जा सकता है।

ख। हालांकि हमने कन्स्ट्रक्टर को निजी बना दिया है, स्थिर सदस्य चर अभी भी उपclass में ले जाया जाएगा।

सी। हम आलसी शुरुआत नहीं कर सकते क्योंकि सब कुछ केवल कक्षा लोडिंग पर लोड किया जाएगा।


खैर एक सिंगलटन सिर्फ एक सामान्य वर्ग है जो तत्काल है लेकिन क्लाइंट कोड से केवल एक बार और परोक्ष रूप से। स्टेटिक क्लास तत्काल नहीं है। जहां तक ​​मुझे स्थिर तरीकों को पता है (स्थैतिक वर्ग में स्थिर विधियां होनी चाहिए) गैर स्थैतिक से तेज हैं।

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


जॉन के बिंदु को चित्रित करने के लिए नीचे दिखाया गया है कि अगर लॉगर एक स्थिर वर्ग था तो नीचे दिखाया नहीं जा सकता है। क्लास कुछ क्लास अपने कन्स्ट्रक्टर में ILogger कार्यान्वयन के उदाहरण की अपेक्षा करता है।

निर्भरता इंजेक्शन के लिए सिंगलटन कक्षा महत्वपूर्ण है।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}

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

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

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

* या मुझे लगता है कि भाषा के आधार पर, पहले उपयोग पर इसे तुरंत चालू किया जा सकता है।


मैंने निम्नलिखित पढ़ा और सोचते हैं कि यह भी समझ में आता है:

आपके व्यवसाय का ख्याल करना

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

ऑब्जेक्ट-ओरिएंटेड थॉट प्रोसेस 4 वें एड पुस्तक से।


यहां एक अच्छा लेख है: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

स्टेटिक कक्षाएं

एकाकी वस्तु

संक्षेप में, मैं केवल उपयोग विधियों को रखने के लिए स्थिर वर्गों का उपयोग करता हूं, और अन्य सभी चीज़ों के लिए सिंगलटन का उपयोग करता हूं।

संपादित करता


सच्चे उत्तर जॉन स्कीट द्वारा यहां एक और मंच पर है

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

एक स्थैतिक वर्ग केवल स्थिर तरीकों की अनुमति देता है।


सिंगलटन को तत्काल माना जाता है, यह केवल एक ही उदाहरण है जिसे तुरंत चालू किया गया है, इसलिए सिंगलटन में एकल

एक स्थिर वर्ग को खुद के अलावा किसी अन्य चीज से तुरंत नहीं बदला जा सकता है।


सिंगलटन परिप्रेक्ष्य परीक्षण से बेहतर दृष्टिकोण है। स्थिर वर्गों के विपरीत, सिंगलटन इंटरफेस को कार्यान्वित कर सकता है और आप नकली उदाहरण का उपयोग कर सकते हैं और उन्हें इंजेक्ट कर सकते हैं।

नीचे दिए गए उदाहरण में मैं इसे समझाऊंगा। मान लें कि आपके पास एक विधि है GoodPrice () जो एक विधि getPrice () का उपयोग करता है और आप सिंगलटन में विधि के रूप में getPrice () को लागू करते हैं।

सिंगलटन जो getPrice कार्यक्षमता प्रदान करता है:

public class SupportedVersionSingelton {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        // calculate price logic here
        return 0;
    }
}

GetPrice का उपयोग:

public class Advisor {

    public boolean isGoodDeal(){

        boolean isGoodDeal = false;
        ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
        int price = supportedVersion.getPrice();

        // logic to determine if price is a good deal.
        if(price < 5){
            isGoodDeal = true;
        }

        return isGoodDeal;
    }
}


In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it. 



  public interface ICalculator {
        int getPrice();
    }

अंतिम सिंगलटन कार्यान्वयन:

public class SupportedVersionSingelton implements ICalculator {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        return 0;
    }

    // for testing purpose
    public static void setInstance(ICalculator mockObject){
        if(instance != null ){
instance = mockObject;
    }

परीक्षा वर्ग:

public class TestCalculation {

    class SupportedVersionDouble implements ICalculator{
        @Override
        public int getPrice() { 
            return 1;
        }   
    }
    @Before
    public void setUp() throws Exception {
        ICalculator supportedVersionDouble = new SupportedVersionDouble();
        SupportedVersionSingelton.setInstance(supportedVersionDouble);

    }

    @Test
    public void test() {
          Advisor advidor = new Advisor();
          boolean isGoodDeal = advidor.isGoodDeal();
          Assert.assertEquals(isGoodDeal, true);

    }

}

अगर हम GetPrice () को लागू करने के लिए स्थिर विधि का उपयोग करने का विकल्प लेते हैं, तो नकली getPrice () को मुश्किल करना मुश्किल था। आप पावर मॉक के साथ स्थैतिक नकल कर सकते हैं, फिर भी सभी उत्पाद इसका उपयोग नहीं कर सकते हैं।


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


हमारे पास हमारे डीबी ढांचे हैं जो बैक एंड के लिए कनेक्शन बनाता है। एकाधिक उपयोगकर्ताओं में गंदे पढ़ने से बचने के लिए हमने सिंगलटन पैटर्न का उपयोग किया है ताकि यह सुनिश्चित किया जा सके कि हमारे पास किसी भी समय एक उदाहरण उपलब्ध है।

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

सिंगलटन स्टेटलेस परिदृश्यों में राज्य को बनाए रखने का एक तरीका प्रदान करता है

उम्मीद है कि आपकी मदद करता है ..


स्टेटिक क्लास: -

  1. आप स्थैतिक वर्ग का उदाहरण नहीं बना सकते हैं।

  2. जब .NET Framework सामान्य भाषा रनटाइम (सीएलआर) द्वारा स्वचालित रूप से लोड किया जाता है जब कक्षा या प्रोग्राम युक्त नामस्थान लोड होता है।

  3. स्टेटिक क्लास में कन्स्ट्रक्टर नहीं हो सकता है।

  4. हम स्थिर वर्ग को विधि में पास नहीं कर सकते हैं।

  5. हम स्टेटिक क्लास को सी # में किसी अन्य स्टेटिक क्लास में वारिस नहीं कर सकते हैं।

  6. एक वर्ग जिसमें सभी स्थिर तरीके हैं।

  7. बेहतर प्रदर्शन (स्थिर तरीके संकलन समय पर बंधे होते हैं)

सिंगलटन: -

  1. आप ऑब्जेक्ट का एक उदाहरण बना सकते हैं और इसका पुन: उपयोग कर सकते हैं।

  2. सिंगलटन इंस्टेंस पहली बार बनाया गया जब उपयोगकर्ता ने अनुरोध किया था।

  3. सिंगलटन कक्षा में कन्स्ट्रक्टर हो सकता है।

  4. आप सिंगलटन कक्षा का ऑब्जेक्ट बना सकते हैं और इसे विधि में पास कर सकते हैं।

  5. सिंगलटन कक्षा विरासत का कोई प्रतिबंध नहीं कहती है।

  6. हम एक सिंगलटन वर्ग की वस्तुओं का निपटान कर सकते हैं लेकिन स्थैतिक वर्ग की नहीं।

  7. तरीके ओवरराइड किया जा सकता है।

  8. आवश्यकता होने पर आलसी लोड हो सकता है (स्थैतिक वर्ग हमेशा लोड होते हैं)।

  9. हम इंटरफ़ेस को कार्यान्वित कर सकते हैं (स्थिर वर्ग इंटरफ़ेस लागू नहीं कर सकता)।


As I understand the difference between a Static class and non-Static Singleton class, the static is simply a non-instantiated "type" in C#, where the Singleton is a true "object". In other words, all the static members in a static class are assigned to the type but in the Singleton are housed under the object. But keep in mind, a static class still behaves like a reference type as its not a value type like a Struct.

That means when you create a Singleton, because the class itself isnt static but its member is, the advantage is the static member inside the Singleton that refers to itself is connected to an actual "object" rather than a hollow "type" of itself. That sort of clarifies now the difference between a Static and a Non-Static Singleton beyond its other features and memory usage, which is confusing for me.

Both use static members which are single copies of a member, but the Singleton wraps the referenced member around a true instantiated "object" who's address exists in addition to its static member. That object itself has properties wherein in can be passed around and referenced, adding value. The Static class is just a type so it doesn't exist except to point to its static members. That concept sort of cemented the purpose of the Singleton vs Static Class beyond the inheritance and other issues.


When I want class with full functionality, eg there are many methods and variables, I use singleton;

If I want class with only one or two methods in it, eg MailService class, which has only 1 method SendMail() I use static class and method.


जॉन स्कीट के उत्तर पर विस्तार करने के लिए

सिंगलटन और स्थिर तरीकों का एक समूह के बीच बड़ा अंतर यह है कि सिंगलटन इंटरफेस को कार्यान्वित कर सकते हैं (या उपयोगी आधार वर्गों से प्राप्त होते हैं, हालांकि यह कम आम आईएमई है), ताकि आप सिंगलटन के चारों ओर पास कर सकें जैसे कि यह "बस एक और" कार्यान्वयन था।

यूनिट परीक्षण करते समय सिंगलटन काम करना आसान होता है। जहां भी आप सिंगलटन को पैरामीटर (कन्स्ट्रक्टर, सेटर्स या विधियों) के रूप में पास करते हैं, आप इसके बजाय सिंगलटन के मॉक या स्टब किए गए संस्करण को प्रतिस्थापित कर सकते हैं।





singleton