DEV Community

Carlos Caballero
Carlos Caballero

Posted on • Edited on

Understanding Design Patterns: Singleton using Hero Examples! (Batman and Spiderman are inside).

There are 23 classic design patterns, which are described in the original book, Design Patterns: Elements of Reusable Object-Oriented Software. These patterns provide solutions to particular problems, often repeated in the software development.

In this article, I am going to describe the how the Singleton Pattern; and how and when it should be applied.

Singleton Pattern: Basic Idea

In software engineering, the **singleton pattern* is a software design pattern that restricts the instantiation of a class to one “single” instance. This is useful when exactly one object is needed to coordinate actions across the system. The term comes from the mathematical concept of a singleton.* — Wikipedia

Ensure a class only has one instance, and provide a global point of access to it. — Design Patterns: Elements of Reusable Object-Oriented Software

The main feature of this pattern is that only a single object is instantiated in each class. Also, a single entry point for the class is created, usually using an accessor method such as getInstance.

The UML’s diagram of this pattern is the following one:

The Singleton class is a single class that has an own attribute called uniqueInstance that stores an instance of the Singleton class. The class constructor is private, and you can only access the instance through an accessor method, which could be getInstance.

The accessor method is responsible for returning the single instance in case it exists or instantiating it in case it has not yet been instantiated.

The Singleton Pattern should be used when:

  1. There must be a single instance of a class, and this class must be accessible by clients from an access point known to them.

  2. The singleton class can be extended by inheritance, and clients must be able to use extended classes without making any changes to it.

The Singleton Pattern has several advantages, summarised in the following points:

  • Have a strict control over how and when clients access to singleton instance. So, you have a controlled access because the singleton class encapsulates its instance.

  • When you need to restrict the number of instances that we create from a class in order to save the system resources.

  • The singleton pattern is an improvement over global variables because it avoids polluting the name space with global variables which only store the singleton instances.

  • The code is more easier to use, understand and test since the singleton simplify the code.

I will now show you how you can implement this pattern using JavaScript/TypeScript. In our case, I have made up a problem in which there is a class named DatabaseConnection which defines two attributes: configuration and getUniqueIdentificator. This class is the connection to our database. The DatabaseConnection is used by several clients (client1 and client2). The following UML diagram shows the scenario that I have just described.

The client code associate is the following ones:

Each client creates a new connection to the database and requests the unique identifier of each of the connections. One of the main consequences of this architecture is that more resources are being used than necessary.

The DatabaseConnection class is the following one:

In the previous class it can be seen that only a private attribute is available with the configuration to the database, and the unique identifier is accessed using the public attribute.

Finally, the sample code for this interaction is as follows:

The result obtained is shown in the following image:

As you can see, each instance of the database has a unique identifier since they are different instances, when the task they perform is exactly the same. In fact, the most smartest would have been to have a single instance to make the connections.

The solution is to use a singleton pattern which only creates one instance of the class. I.e, the new UML diagram using the singleton pattern is shown below:

The code associate to the DatabaseConnection is the following one:

The only access point to the instance is using the getDatabaseConnection static method, which will create a new instance in case that the instance does not exist or will get it. In this way, clients are slightly modified to use this instance instead of creating their own instance:

The result after these modifications in the execution of the program is the shown in the following image:

I have created two npm scripts that run the two examples shown here after applying the Singleton pattern.

npm run example1-problem
npm run example1-singleton-solution1

Another interesting example which is resolved using singleton pattern is when there are several class which must to be singleton. For example, a set of heroes as Spiderman and Batman are singleton. In the following UML’s diagram you can see this situation:

The code associate to the clients is the following ones:

Next, we will create our heroes, which will be unique. First of all we will define a common interface of the information that each of them will contain:

Our heroes are unique but share certain attributes and methods, for this we have defined a parent class called HeroBase that contains the common features of both Spiderman and Batman. This class is the following one:

Both Batman and Spiderman have implemented the Singleton pattern in their construction and store a reference to the only object of each class (our hero!). These classes are following ones:

Finally, the sample code for this interaction is as follows:

The result obtained is shown in the following image:

I have created a npm scripts that run the example shown here after applying the Singleton pattern.

npm run example2-singleton-solution1

The singleton pattern can avoid complexity in your projects because you will have strict control of the instantiation of a class in a single point well known by the clients. Furthermore, it is a pattern that saves system resources because instead of instantiating a set of classes that perform the same task, a single instance of that class will be used. However, this pattern has a very bad reputation, even coming to be considered an anti-pattern because this pattern is really creating global variables that can be accessed and changed from anywhere in the code.

The most important thing has not implement the pattern as I have shown you, but to be able to recognise the problem which this specific pattern can resolve, and when you may or may not implement said pattern. This is crucial, since implementation will vary depending on the programming language you use.

Conclusion

The singleton pattern can avoid complexity in your projects because you will have strict control of the instantiation of a class in a single point well known by the clients. Furthermore, it is a pattern that saves system resources because instead of instantiating a set of classes that perform the same task, a single instance of that class will be used. However, this pattern has a very bad reputation, even coming to be considered an anti-pattern because this pattern is really creating global variables that can be accessed and changed from anywhere in the code.

The most important thing has not implement the pattern as I have shown you, but to be able to recognise the problem which this specific pattern can resolve, and when you may or may not implement said pattern. This is crucial, since implementation will vary depending on the programming language you use.

More more more...

Originally published at https://www.carloscaballero.io on May 2, 2019.

Top comments (0)