Menu Close

Object Oriented Design Pattern: Singleton

Explanation

The Singleton design pattern is a creational pattern that ensures only one instance of a class will be instantiated at maximum. You can use this to prevent that different versions of an instantiation of a class exists. There are multiple ways to implement Singletons, the following examples will show a way to do it.

Class diagram
Class diagram

Use cases:

  • You need a class that is easily accessible to all other classes.
  • You want to be sure only one instance of the specific class exists.
  • You need variables/function to be globally accessible, such as global configuration variables.

Pitfalls:

  • Too many Singleton classes in a project are counter-intuitive to object-oriented design principles.

Java Example

package com.chosengambit.designpatterns;

public class Main {

    public static void main(String[] args) {
        Singleton s1 = Singleton.i();        
        s1.setStr("Hello World!");
        System.out.println(s1.getStr());
        
        Singleton s2 = Singleton.i();
        s2.setStr("This is s2");
        
        System.out.println(s1.getStr()); // overwritten, because it's the same instance
        System.out.println(s2.getStr());
        
        System.out.println(s1.equals(s2));        
    }
}

Java

package com.chosengambit.designpatterns;

public class Singleton {
    
    private static Singleton instance;
    String str;
    
    private Singleton() { } // inaccessible constructor
    
    public static Singleton i() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance; // always return the same instance
    }
    
    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
}
Java
Output:

Hello World!
This is s2
This is s2
true

Python Example

from Singleton import Singleton

s1 = Singleton()
s1.var = "Hello, world!"
print(s1.var)

s2 = Singleton()
s2.var = "This is s2"

print(s1.var)
print(s2.var)

print(id(s1) == id(s2))
Python

class Singleton:
    __instance = None
    __var = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super().__new__(cls, *args, **kwargs)
        return cls.__instance

    @property
    def var(self):
        return self.__var

    @var.setter
    def var(self, value):
        self.__var = value
Python
Output:

Hello, world!
This is s2
This is s2
True

Conclusion

The Singleton Design Pattern comes in handy when you want to make sure only a single instance of an object exists. It comes in handy when you need functionality or variables to be globally accessible. To prevent a compromised object-oriented design, it’s best to not use the Singleton too frequently.

References

Freeman, E., Bates, B., & Sierra, K. (2004). Head first design patterns.

Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software.

Wikipedia contributors. (2024, 10 september). Software design pattern. Wikipedia. https://en.wikipedia.org/wiki/Software_design_pattern

Related Posts