Patterns Revisited Singleton

portrait photo of Josh Angolano
By Josh Angolano

A simple creational pattern

Globals are bad. Data should be encapsulated and only available when needed. These are some of the first things you learn when you start to program. If there are multiple actors that can write to shared data, side affects can occur. However there are times when having a single instance of data is required. In the singleton pattern there is only one instance of a class, which you cannot explicitly create.

Data that doesn’t change often, but is needed throughout your application. Some Examples:

How to create a singleton

The singleton pattern is one of the simplest patterns. To create a singleton you only need one class. The examples below show the class being initialized with data that cannot change. In the examples, I hardcoded a URL for simplicity, however in practice data could be read from a file, network location or a service.

Java

public class Single 
{ 
    private static final Single instance = new Single(); 
    
    private String url; 
    private Single() 
    { 
        url = "https://www.leantechniques.com";
    } 
    public static Single getInstance(){ 
            return instance; 
    } 

    public String getUrl(){
        return url;
    }
} 

//Usage
private Single single = Single.getInstance();
private String url = single.url;

Kotlin

object Single{
    val url = "https://www.leantechniques.com"
}

//Usage
val string = Single.url

Swift

class Single {
    let url = "https://www.leantechniques.com"

    static let sharedInstance = Single()

    private init() {
    }
}

//Usage
let single = Single.sharedInstance
let url = single.url

Gotchas using a singleton

If you create a singleton that allows the data to change after instantiation, you have to be aware of side effects and thread safety. This is also dependent on the language that you choose. Kotlin objects are thread safe, Java classes are not. The example below is of a Singleton written in Java that is thread safe.

public class Single
{
    private static Single instance;

    private String url;

    private Single() {
        url = "https://www.leantechniques.com";
    }

    synchronized public static Single getInstance(){
        if(instance!=null) {
            return instance;
        }else{
            return new Single();
        }
    }

    public void setUrl(String url){
        this.url = url;
    }

    public String getUrl(){
        return url;
    }
}

Testing a class that uses mocks.

Another challenge you might come across is how to mock a singleton. For example using Mockito to test a Java program you can’t mock static methods. You might need to pull in a library such as PowerMock. If you are writing code in Kotlin you can use a library such as Mockk.

On to the facade pattern…

In the next rant, I am going to explore a the facade pattern. The facade is a structural pattern as opposed to a creational pattern.

Published: 05 Jun 2020