What are the real world applications of the singleton pattern?

后端 未结 10 555
南旧
南旧 2021-02-01 07:22

Duplicate

On design patterns: When should I use the singleton?

class Singleton
{
    private static Singleton instance;

    private Singleton() {}

             


        
相关标签:
10条回答
  • 2021-02-01 07:47

    Simple. What does a singleton do?

    • It provides global access to an instance of an object, and
    • It guarantees that no more than one instance of that type can ever be created.

    So you use a singleton when you need both of these things.

    And that is rare. Globals are generally speaking, bad. We tend to avoid them when possible. And building your application around the assumption that "if more than one instance exists, it is an error" is dangerous, because you typically find out the assumption didn't hold. Perhaps you want to be able to create multiple instances locally, for caching purposes. Perhaps it turns out you need more than one database, more than one log, or perhaps threading performance requires you to give each thread its own instance.

    In any case, you don't need to enforce the "only one instance may exist" assumption. If you only need one instance, simply create only one instance. But leave the constructor publicly visible so that more instances can be created if it turns out to be necessary.

    In other words, both of the features offered by a singleton are actually negatives. In general, we don't want our data to be globally visible, and we don't want to take away flexibility for no reason.

    If you do need one of the features offered by a singleton, implement that one feature, without the other. If you need something to be globally accessible, make it a global. Not a singleton. And if you do need to enforce that only one instance will exist (I can't think of any plausible situations where you'd want this), then implement that, without the global visibility.

    The only real world application of singletons I've ever seen has been "an architect has read the GoF book, and decided to cram design patterns in everywhere.", or "some programmer stuck in the 80's isn't comfortable with the whole "object oriented" thing, and wants to code procedurally, which means storing data as globals. And singletons sounds like an "OOP" way to make globals without getting yelled at".

    The key point is that a singleton mixes two, very different, and each very rarely needed, responsibilities. Typically, you want at most one of those in any given object.

    0 讨论(0)
  • 2021-02-01 07:52

    Note that this code is not thread safe:

    get   
    {
       if (instance == null)   
          instance = new Singleton();   
        return instance;   
    }   
    

    One thread could enter the function, get past the test for null and then be suspended. A second thread could then start and get past the null test. From that point on, both threads will at some point create their own copy of the sungleton object, only one of which gets used.

    This may not matter so much in a GC language like C#, but if the singleton controls rresources other than memory, then it does matter. You need to use the double-checked locking pattern to prevent it.

    0 讨论(0)
  • 2021-02-01 07:52

    You could find the singleton pattern useful if you have a resource that costs a lot to get initialized, and that you use several times, such as an object context when you use an ORM or a connection of some sort.

    Obviously you must pay attention that keeping that thing alive does not cost you more than recreating it every time.

    0 讨论(0)
  • 2021-02-01 07:58

    One way I've used a singleton is to implement a "main controller" object for an application. This was a bit like the Application object you get with VBA.

    This object performed various startup and shutdown tasks. It also provided access to application-wide settings and services. This included values of command-line parameters and the logging service, among others.

    0 讨论(0)
  • 2021-02-01 08:04

    A good example of where I've used a Singleton is in an application that had to call a web service component from several places within the application. I needed to maintain state, initialize some fields, and maintain a queue of calls and callbacks, so I couldn't just make static calls. But I wanted only one instance to be reused throughout the application. I implemented this "service" class as a singleton, so that I could call it all over the app in response to many different events, but they were all handled in one single place.

    In my experience, I've used singletons where an object was going to be used many times over the life of the app, required initialization, and/or was memory heavy. Basically where having only one instance of a class where you could potentially have many instances and it would be costly to do so.

    0 讨论(0)
  • 2021-02-01 08:05

    Jon Skeet, THE_SKEET, has a great article exemplifying various ways to implement correctly (Thread safe, lazy, performant) the Singleton pattern.

    Go read it here.


    By popular demand (er... downvote) I reproduce the Skeet version:

    public sealed class Singleton
    {
        Singleton()
        {
        }
    
        public static Singleton Instance
        {
            get
            {
                return Nested.instance;
            }
        }
    
        class Nested
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static Nested()
            {
            }
    
            internal static readonly Singleton instance = new Singleton();
        }
    }
    

    Here, instantiation is triggered by the first reference to the static member of the nested class, which only occurs in Instance. This means the implementation is fully lazy, but has all the performance benefits of the previous ones. Note that although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here. That doesn't raise any other problems, though, as the class itself is private. The code is a bit more complicated in order to make the instantiation lazy, however.

    0 讨论(0)
提交回复
热议问题