time

Singleton design pattern in Java, Kotlin, Python and Swift

Creational Design Patterns provide solution to instantiate an object in the best possible way for specific situations. Following design patterns come under this category.

Singleton pattern ensures that only one object of a particular class is ever created.

Sometimes it’s important for some classes to have exactly one instance. There are many objects we only need one instance of them and if we, instantiate more than one, we’ll run into all sorts of problems like incorrect program behavior, overuse of resources, or inconsistent results.

Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.

There are only two points in the definition of a singleton design pattern:

  • There should be only one instance allowed for a class.
  • We should allow global point of access to that single instance.
dp_singleton.gif

This sequence diagram shows how simple it is for a client to get an instance of the Singleton.

dp_singleton_seq.png

Usage of Singleton design pattern:

  • Singleton pattern is mostly used for memory save because object is not created at each request. Only single instance is reused again and again.

Java

// file Singleton.java 
class Singleton {
    private static Singleton instance;
    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null)
            instance = new Singleton();

        return instance;
    }

    public void doSomething() {
        System.out.println("Singleton");
    }

    // serialization
    protected Object readResolve() {
        return getInstance();
    }    
}

// file Demo.java
public class Demo {
   public static void main(String[] args) {
      Singleton object = Singleton.getInstance();
      object.doSomething();
   }
}

Python 3

Create Singleton using metaclass.

class SingletonType(type):
    instance = None
    def __call__(cls, *args, **kw):
        if not cls.instance:
             cls.instance = super(SingletonType, cls).__call__(*args, **kw)
        return cls.instance

class Singleton(object):
    __metaclass__ = SingletonType

    def do_something(self):
        print('Singleton')


s = Singleton()
s.do_something()

Kotlin

Kotlin just introduces a reserved keyword for that. Behold, an object as follows:

object MySingelton{}

You don't need curly brackets there. They're just for visual consistency. This combines declaration and initialization in one keyword. From now on, MySingleton can be accessed from anywhere in your code, and there'll be exactly one instance of it.

Of course, this object doesn't do anything interesting. Let's make it count the number of invocations instead:

object CounterSingleton {
    private val counter = AtomicInteger(0)

    fun increment() = counter.incrementAndGet()
}

For now, we test it only to see how we call our Singleton:

for (i in 1..10) {
    println(CounterSingleton.increment())
}

This will print numbers between 1 and 10, as expected. As you can see, we don't need the getInstance() method at all.

Objects can't have constructors. If you want some kind of initialization logic for your Singleton, such as loading data from the database or over the network for the first time, you can use the init block instead:

object CounterSingleton {
    init {
        println("I was accessed for the first time")
    }
    // More code goes here
}

It is also demonstrated that Singletons in Kotlin are initialized lazily, and not eagerly, as some could suspect from the ease of their declaration. Just like regular classes, objects can extend other classes and implement interfaces.

Swift

Let's look at how we implement the singleton pattern with Swift. The following code example shows how to create a singleton class:

class MySingleton {
    static let sharedInstance = MySingleton()
    var number = 0
    private init() {}
}

We can see that, within the MySingleton class, we created a static constant named sharedInstance, which contains an instance of the MySingleton class. A static constant can be called without having to instantiate the class. Since we declared the sharedInstance constant static, only one instance will exist throughout the lifecycle of the application, thereby creating the singleton pattern.

We also created the private initiator that will restrict other code from creating another instance of the MySingleton class.

Now, let's see how this pattern works. The MySingleton pattern has another property, named number, which is an integer. We will monitor how this property changes as we use the sharedInstance property to create multiple variables of the MySingleton type, as shown in the following code:

var singleA = MySingleton.sharedInstance
var singleB = MySingleton.sharedInstance
var singleC = MySingleton.sharedInstance
singleB.number = 2
print(singleA.number)
print(singleB.number)
print(singleC.number)
singleC.number = 3
print(singleA.number)
print(singleB.number)
print(singleC.number)

In this example, we implemented the singleton pattern using a reference (class) type because we wanted to ensure that only one instance of the type existed throughout the application. If we implemented this pattern with a value type, such as a structure or an enumeration, we would run the risk of there being multiple instances of the type. If you recall, each time we pass an instance of a value type, we are actually passing a copy of that instance, which means that, if we implemented the singleton pattern with a value type, each time we called the sharedInstance property we would receive a new copy, which would effectively break the singleton pattern.