DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 966,904 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Design Patterns: Singleton
Ryan
Ryan

Posted on • Updated on

Design Patterns: Singleton

Hey guys, thanks for being here! I've decided to start writing some posts as I review design patterns. Design patterns help provide a general and reusable solution to recurring software development problems. First, we're going to be taking a look at the Singleton pattern.


Overview


Definition

Singleton: a single person or thing of the kind under consideration.
The Singleton design pattern is a creational design pattern. It refers to a class that has only one instance in existence at any given time. If we try to instantiate an instance of the Singleton class for a second time, the new variable also points to the first instance that was created earlier.
Let's take a look at the implementation of this pattern and then talk about some problems it can help solve.


Implementation

To achieve the Singleton pattern, the class has two main characteristics:

  1. The constructor is private.
  2. There is a static method that returns the Singleton instance.

These characteristics allow us to first create an instance for the class if it has yet to be instantiated, and then return that instance whenever the class is called for.

Using C#, the pattern looks like this:

using System;

public class Program
{
    public static void Main()
    {
        Singleton object1 = Singleton.Instance();
        Singleton object2 = Singleton.Instance();
        if (object1 == object2)
            Console.WriteLine("They're the same instance!");
    }
}

/// <summary>
/// The Singleton class.
/// </summary>
class Singleton
{
    private static Singleton myInstance;

    // 1. The constructor is private.
    private Singleton() { }

    // 2. Static method that returns the Singleton instance.
    public static Singleton Instance()
    {
        if (myInstance == null)
            myInstance = new Singleton();

        return myInstance;
    }
}

In this case, the program would write the string "They're the same instance!". You can play with this code here on .NET Fiddle


Real-World Examples

Sweet, now we're able to write a class that will only have one instance in our program at a time! What can we do with that? What kind of recurring software development problems can this pattern help solve?

A Singleton pattern is especially useful when accessing some sort of resource that the entire application is making use of that may have issues when being accessed by more than one instance at a time (it helps solve concurrency issues). There are a lot of common development situations where this might be the case, like hardware interface access, and logging data to a file.

In the case of hardware interface access, we may be connecting to hardware that will have concurrency issues when being accessed by multiple instances. For example, the Singleton pattern can help a printer print documents in a certain order, avoiding deadlock situations. In the case of logging data to a file, we may have multiple clients logging to a single file at the same time. The Singleton pattern can help prevent problems with concurrent access to this log file.


Disclaimer: There are a lot of resources for learning design patterns, and they can be implemented in different ways. I would recommend exploring more resources when finished with this post.

Top comments (13)

Collapse
 
paulsmithkc profile image
Paul Smith • Edited on

Do not use a Singleton to solve concurrency problems. You will end up creating concurrency problems, where there weren't concurrency problems to begin with.

Without a Singleton typically every thread will have it's own object which will usually be just fine. However with a Singleton every thread in your application will end up with the same instance of said object(s) and that is gaurenteed, even for trivial cases, to cause concurrency problems.

Instead of implementing Singleton, use frameworks and libraries with proper support for concurrency, that do not force/encourage you to create Singletons.

Collapse
 
antomor profile image
Antonio Morrone • Edited on

Hy Ryan,
Thank you for the clear explanation. If interested, you can find out a detailed description of the problems related to c# singleton implementations.

Collapse
 
vdedodev profile image
Vincent Dedo

Singletons are always overused, and when that happens people with opinions roll in telling you it's an anti-pattern. I've found that most of the time I don't actually need a singleton, it just makes life easier. I haven't seen a really bad usage of it yet, so I'd like to see one if those people are in a sharing mood.

Collapse
 
gochev profile image
Nayden Gochev

I find this wrong and buggy, if two thread invoke the Instance at the same time there is a chance two variables to be created and in fact two different instances to be received by the two threads.

I am not a C# guy, sorry but usually in Java volatile and the double check locking helps I believe you can do the same in C#. Also I know in C# you have a Lazy<> which should be used ... but this pattern implementation is not good :( :(

Maybe there is some additional static magic that C# do, but I find it a bit smelly :D

I think the correct implementation is

public sealed class Singleton 
{
    private static readonly Lazy<Singleton>lazy = new Lazy<Singleton>(()=>new Singleton());

    public static Singleton Instance
    { 
        get 
        { 
            return lazy.Value; 
        } 
    }

    private Singleton() 
    {
    }
}

P.S. sorry for the wrong formatting (if it is wrong) I use { on the same line... :D:D:D so :D maybe I messed something :D

Collapse
 
gochev profile image
Nayden Gochev • Edited on

oh yes also en.wikipedia.org/wiki/Double-check...

here you can check the proper implementation of your example

public class MySingleton {
    private static object myLock = new object();
    private static volatile MySingleton mySingleton = null; // 'volatile' is unnecessary in .NET 2.0 and later

    private MySingleton() {
    }

    public static MySingleton GetInstance() {
        if (mySingleton == null) { // 1st check
            lock (myLock) {
                if (mySingleton == null) { // 2nd (double) check
                    mySingleton = new MySingleton();
                    // In .NET 1.1, write-release semantics are implicitly handled by marking mySingleton with
                    // 'volatile', which inserts the necessary memory barriers between the constructor call
                    // and the write to mySingleton. The barriers created by the lock are not sufficient
                    // because the object is made visible before the lock is released. In .NET 2.0 and later,
                    // the lock is sufficient and 'volatile' is not needed.
                }
            }
        }
        // In .NET 1.1, the barriers created by the lock are not sufficient because not all threads will
        // acquire the lock. A fence for read-acquire semantics is needed between the test of mySingleton
        // (above) and the use of its contents. This fence is automatically inserted because mySingleton is
        // marked as 'volatile'.
        // In .NET 2.0 and later, 'volatile' is not required.
        return mySingleton;
    }
}

without lazy, az you can see volatile is NOT required now days, but double checked locking is !

Collapse
 
muhammadhasham profile image
Muhammad Hasham

Great write-up! another use case for singleton pattern can be that of a database connection. It is encourage to have a single database connection opened that should be used by all resources. :-)

Collapse
 
josefsabl profile image
josefsabl

Please, don't use singleton for DB connections.

Collapse
 
fathonir profile image
Fathoni Rokhman

Why? Is there any problems if we implemented it?

Thread Thread
 
jonathanhiggs profile image
Jonathan Higgs

One thread calls conn.Close() just before the other tries to execute a query...

Collapse
 
jignex profile image
Jignesh Thummar

Very good explanation, Magento 1 used to use Singleton pattern widely specially for read only objects

Collapse
 
josefsabl profile image
josefsabl • Edited on

There are not many situations where singleton is cool and I mostly consider it an antipattern. The only defensible use I found so far are the sort of meta-features like logging or profiling as you are not always able to inject these as services.

Collapse
 
rolandcsibrei profile image
Roland Csibrei • Edited on

Beware, in some cases in a multithread application you could end up with more "singleton" instances if you don't use lock. You can lock the whole factory method or the singleton object.

Collapse
 
yoann_buzenet profile image
Yoann Buzenet

Thanks for the article!

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.