Cidenet+Blog+Clean Dev Practices+Singleton

Singleton

What is it? What problem does it solve?

The Singleton pattern is used to ensure that a class has a maximum of one instance and provides a global point of access to this instance if there are object creations in the code.

This pattern solves two problems:

  1. Ensure that a class has a single instance: This can be useful when you need to control access to a shared resource, for example, a file or an interface component.
  2. Provide a global access point to that instance: The Singleton pattern allows access to an object from anywhere in the program. However, it also protects that instance from being updated by other code.

Diagram

 

Singleton: Defines a method that allows clients to access their only instance. it’s also responsible for the creation of your only instance.

The client code accesses the Singleton instance only through the method granted by the Singleton itself.

Example

The Singleton pattern can be used in the Factory pattern to have a single object for each ConcreteCreator. In this example, we will illustrate the structure of the Factory pattern and convert a ConcreteCreator into a Singleton. This is done because the objects of each ConcreteCreator when created will always be the same, and it is not optimal to have several instances that are the same.

For this example we will take the JSONConverter class; To make this class a Singleton, you must:

  • Create within the JSONConverter class a private instance of the same class.
private static JSONConverter jsonConverter;
  • Make the class constructor private:
private JSONConverter(){}
  • Create the getInstance method, which is the access point of the private instance.
  • This method initializes the private object if it has not been called before. If it has been called before, the previously created instance is simply returned.
public static JSONConverter getInstance() {
    if(jsonConverter == null) {
        jsonConverter = new JSONConverter();
    }
    return jsonConverter;
}
  • In the Director method, which selects which ConcreteCreator to return, the new must be changed by the call to the method exposed by JSONConverter.
public static Converter getConverter(ConverterType format) {
    switch (format) {
        case JSON:
        return JSONConverter.getInstance();
    }
}

To prove that the JSONConverter objects are identical, two unit tests are carried out (image 6), one where two ConcreteCreators of the JSON type are compared and another test where two ConcreteCreators of the XML type are compared. We notice how for JSON the objects point to a single object and how for XML there are two different instances. With this pattern, we save memory space by avoiding the creation of multiple objects that are designed to be the same.

It should be noted how thanks to the Factory pattern, a change could be made to a ConcreteCreator and its use in the unit tests was not affected, thanks to the Creator, it is always certain that it will return a Converter without importing this as you got it.

@Test
public void shouldGetSameConcreteCreatorInstance() {
    assertEquals(Director.getConverter(ConverterType.JSON), 
                 Director.getConverter(ConverterType.JSON));
}

@Test
public void shouldGetDifferentConcreteCreatorInstance() {
    assertNotEquals(Director.getConverter(ConverterType.XML), 
                 Director.getConverter(ConverterType.XML));
}

Conclusions

  • Because the Singleton class encapsulates your instance, you can have tight control over how a client accesses this instance.
  • The Singleton object is initialized only when it is required the first time, if it has never been required, it is not initialized.
  • Abstract Factory, Factory Method, Builder and Prototype can be implemented as Singleton.

The code example can be found in https://bit.ly/3k60MsS

Sources


Contact us

Allow us to contact you

    Medellín - Colombia

  • Calle 47D #72-29
  • (+57) 4 3222567
  • comunicaciones@cidenet.com.co

    United States

  • 1200 Colorado Blvd, Denver Colorado 80220
  • (+1) 7723619239
  • jceballos@cidenet.net
WhatsApp
>