This blog focuses on Singleton Design Pattern and its uses in an MVC application. Before we start with the main topic, let us first understand what design patterns in programming are and why they are important in software engineering.
Definition of Design Patterns in Programming:
In simple terms, design patterns in programming are the best practices used by software developers to solve problems that arise when software is being developed.
Why are design patterns important in programming?
Software design patterns have two major benefits with regard to programming.
- They use a proven solution that is implemented so that you get to solve issues related to software development.
- Secondly, software design patterns lead to more efficient communication between designers when programming. While discussing system design, they can mentally picture or recall high-level designs when the pattern used to solve a particular issue is referred to by name. Such design patterns can be in Java or Python.
What is the Singleton Design Pattern?
With the Singleton Design Pattern, the instantiation of a class is restricted to one object. This is how this design pattern works in java or any other programming language because it is a creational design pattern with regard to programming. Below is a list of all the software design patterns:
Singleton Design Pattern is a type of creational design pattern as mentioned by the ‘Gang of Four’. For instance, in the singleton design pattern in Java, only one object of a class is created throughout the application.
- Only one class instance must exist.
- Declare all such classes with private constructors
- Create a class method that would return the object of the class.
- The class instance is assigned to a private static variable.
- Visual Studio 2013 or above (for practical understanding)
- C# language using .NET framework( for practical understanding)
- To understand sealed classes: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed
- To understand private constructors: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/private-constructors
Practical demonstration of a non-Singleton Design Pattern implementation:
- Let us start by creating a simple MVC application as shown below. I have named the application as SingletonPattern.
- We will be using .NET Framework 4.8 and Visual studio 2019 for this:
- Once it is ready, the visual studio application looks as shown below:
- To this application, let us add a new project in the form of a class library.
- As shown below, a Singleton class is created in the service. The Singleton class is responsible for providing a single instance of the class. Right now, the class does not behave as a singleton class as it does not match the implementation guidelines mentioned above.
- As of now, the class has a method GetMessage which returns a string. Let us now add a controller which would invoke the ‘GetMessage’ function.
- Let us name the controller as SingletonExampleController. It has a View action method that calls the GetMessage function from the service layer:
- To the Singleton class, let us add some more methods:
- To demonstrate the importance of Singleton design pattern, let us add another controller class called MessageController:
- To understand the count of objects that are created, let us modify the SingletonExample controller as below:
- Let us now create the View page for both the controllers:
- The Index.cs html page is as follows:
- The same Singleton service class is instantiated from multiple controllers. This will cause multiple object creation of the same class in the application. To test that, let us run the GetObjectCount method:
To prevent this, let us modify the Singleton service class in such a way that it will create only one instance of the Singleton service class. We must carefully follow the implementation guidelines while we achieve the Singleton Design Pattern.
Practical demonstration of Singleton Design Pattern:
- Let us modify the Singleton service class as shown below:
Private constructors will prevent object creation of the class. Sealed keyword will prevent the implementation of the class. Now, instead of using the ‘new’ keyword for object initialization, the controller methods will invoke GetInstance() method to get the instance of the Singleton service class.
- The controller methods will throw an error when a new object is created. Hence object creation is completely handled by the service layer.
- This can be solved by calling the GetInstance method of the Singleton service class which will return the object of the desired class
Disadvantages of Singleton pattern:
- They are generally used as a global instance, and I will tell you why that is so not recommended. In your code, instead of exposing the dependencies of your application through the interfaces, you hide them. Ideally, when you make something global, you should also be able to pass it around. When you cannot do that, it is a code smell.
- They control their own creation and entire life cycle, thereby violating the single responsibility principle.
- The code is tightly coupled because of the inherent nature of the singleton pattern. To elaborate, some of the SOLID principles are not taken into account while using the Singleton design pattern. Therefore, in many cases, it becomes rather difficult to fake them out under tests.
- They carry the same state around for the lifetime of the application. This means your testing is prone to another hit. How? You can find yourself in a situation where tests need to be ordered. This is absolutely forbidden for unit tests. The reason for this is that each unit test should be independent in comparison to any other similar test.