Introducing the Singleton design pattern

Introducing the Singleton design pattern

Read Time : 4 Minutes

Friday, 24 March 2023

Design patterns are proven solutions to software design problems. They help improve code quality, promote reusability, and increase maintainability. We use them to save time and produce quality, extensible and flexible code. In this article, we are going to introduce the Singleton design pattern.

The Singleton pattern is a creational design pattern that ensures that a class has only one instance and provides only one access point to that instance.

The Singleton pattern includes the following elements:

  • Singleton class: It is a class designed to have only one instance. It usually has a private constructor and a static method to obtain that instance.
  • Instance variable: In the Singleton class, there is a private static variable of the same class type that holds the only available instance.
  • GetInstance method: This method is a static method in the Singleton class by which we get the existing instance. If the instance is not initialized, we initialize it before returning the instance.

The Singleton pattern ensures that only one instance of the Singleton class can be created and that there is only one way to access it. The benefit of this pattern is determined when we want to use the same pattern in different parts of the program.

 

Difference between Singleton class and Static class

The main difference between Singleton and Static classes is that a Singleton class allows you to create an instance of a class. Whereas a static class does not allow you to create any instance of the class. And all members are accessible using the class name.

In general, the Singleton pattern is useful when you need to manage a shared resource, such as a database connection, configuration data, or a hardware device, and you want to ensure that there is only one instance of the class that manages that resource. Static classes are useful when you have a set of utility methods that do not need to maintain state and can be called from any point in the code without having to create an instance of the class.

 

Below is an example of the Singleton pattern in C#:

public sealed class Singleton
{
    private static Singleton instance = null;
    private Singleton()
    {
        // Private constructor to prevent other instances from being created
    }
    public static Singleton GetInstance
    {
        get
        {
                if (instance == null)
                {
                   instance = new Singleton();
                }
                return instance;
            }
    }
}

In this example, the Singleton class is defined as sealed to prevent inheritance and ensure that it can only have one instance. The instance variable is defined as private and static and is initialized with null value.

The GetInstance property/method is a public static property/method that provides access to the instance. Checks its value to make sure the instance has been created and returns it if an existing instance has already been created. To use the instance, you just need to call the Singleton.GetInstance property from anywhere in the application. Defining the Singleton class like previous example, is not safe in applications that use multiple threads.

In order to be able to use the Singleton pattern in multi-threaded programs, the code must be changed as follows:

public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();
    private Singleton()
    {
        // Private constructor to prevent other instances from being created
    }
    public static Singleton GetInstance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                   instance = new Singleton();
                }
                return instance;
            }
        }
    }
}

This change causes that if several threads want to access a common part of the memory at the same time, they cannot do it in parallel. Therefore, each thread must execute the code in the lock block in turn. As a result, the sample is set in the first thread and we will not enter the condition in the next threads.

To read about other design patterns, you can use the list below. There is also a code repository on GitHub that includes all the design patterns.

design patterns

Creational:Factory Design Pattern
Builder Design Pattern
Singleton Design Pattern
Prototype Design Pattern
Abstract Factory Design Pattern
Structural:Adapter Design Pattern
Bridge Design Pattern
Composite Design Pattern
Decorator Design Pattern
Facade Design Pattern
Flyweight Design Pattern
Proxy Design Pattern
Behavioral:Chain of Responsibility Design Pattern
Command Design Pattern
Interpreter Design Pattern
Mediator Design Pattern
Memento Design Pattern
Observer Design Pattern
State Design Pattern
Strategy Design Pattern
Template Method Design Pattern
Visitor Design Pattern
Iterator Design Pattern
  • Share:
reza babakhani
Reza Babakhani

I am Reza Babakhani, a software developer. Here I write my experiences, opinions and suggestions about technology. I hope that what I write is useful for you.

Latest post

Service Mesh Simplifying Microservice Communication

In the ever-evolving landscape of software development, microservices architecture has gained considerable popularity due to its scalability, flexibility, and extensibility. However, as the number of microservices in an application increases, it becomes increasingly challenging to manage their communication and ensure that they are all properly visible. This is where Service Mesh comes into play.

The Importance of Edge Computing

Due to the speed of technological evolution, one of the concepts that has attracted a lot of attention and changes the way we interact with digital systems is edge computing.

What is event-driven architecture?

Event-driven architecture (EDA) is a software design pattern that has become increasingly popular in modern software development. In this architecture, the flow of data is determined by the occurrence of events. Unlike traditional centralized systems that are constantly checking for new status. Event-driven architecture is especially useful for systems that need to process large amounts of data in real-time.

leave a comment