Singleton
Singleton is like a single resource which is being shared among multiple users; for example - sharing a single washing machine among all the residents in a hotel or sharing a single appliance like refrigerator among all the family members.
From Wikipedia, "The singleton pattern is a software design pattern that restricts the instantiation of a class to one object.”
Use Case
Let’s think about the customer who has multiple Windows-based (Desktop) applications currently in use for different financial purposes. Now, they want us to provide a solution to add the printing feature in all the applications they have.
One thing which is clearly stated is that they want printing functionality to be added to all their applications, which means, we need to create a printing library or class that can be shared or accessed from multiple applications.
For such kind of implementation where we have to restrict the instantiation of a class to one object meaning a single instance of a class that can be shared or accessed from multiple, Singleton pattern is the best we can follow. Now, let’s have a look at the implementation.
Classic & Simple Implementation
- ///<summary>
- /// This class is the implementation of singleton design pattern which restricts the instantiation of a class to one object
- ///</summary>
- publicsealedclassPrinter {
- //A static variable which holds a reference to the single created instance
- privatestaticPrinter _printerInstance;
- // A static variable which implements a Queue data structure and holds a documents to be printed
- privatestaticQueue < String > _queue = newQueue < string > ();
- ///<summary>
- /// private and parameterless constructor that prevents other classes from instantiating it
- ///</summary>
- private Printer() {}
- ///<summary>
- /// This method is to get the instance of Printer class
- ///</summary>
- ///<param name="instanceName">Name of an instance</param>
- ///<returns>An instance of Printer class</returns>
- publicstaticPrinter GetPrinterInstance(string instanceName) {
- //If there is no instance of printer class exists then instantiate
- if (_printerInstance == null) {
- Console.WriteLine("{0} printer object created", instanceName);
- _printerInstance = newPrinter();
- }
- return _printerInstance;
- }
The above code works as expected when it is accessed from a single thread or application but there is a possibility that the above code “if (_printerInstance == null)” might not work as expected when accessed from multiple threads or applications meaning when accessed from multiple threads. Simultaneously, the code “if (_printerInstance == null)” might return True for concurrent requests and create separate instances.
Let’s have a look at the request from multiple threads simultaneously and the corresponding response.
- staticvoid Main(string[] args) {
- InitializePrinterObject();
- }
- ///<summary>
- /// This method Initializes three Task and run at the same time with very
- /// less time gap in between. These task initialize Printer object and add document to printer queue
- ///</summary>
- staticvoid InitializePrinterObject() {
- Printer firstPrinterObject = null;
- Printer secondPrinterObject = null;
- Printer thirdPrinterObject = null;
- Task task1 = Task.Factory.StartNew(() => {
- firstPrinterObject = InitializePrinterObjectAndAddDocument("First", "First-Document");
- });
- Task task2 = Task.Factory.StartNew(() => {
- secondPrinterObject = InitializePrinterObjectAndAddDocument("Second", "Second-Document");
- });
- Task task3 = Task.Factory.StartNew(() => {
- thirdPrinterObject = InitializePrinterObjectAndAddDocument("Third", "Third-Document");
- });
- Task.WaitAll(task1, task2, task3);
- Console.WriteLine("All threads complete");
- Console.WriteLine("Are these First Printer Object And Second Printer Object Same - {0} ", firstPrinterObject.Equals(secondPrinterObject) ? "Yes" : "No");
- Console.WriteLine("Are these First Printer Object And Third Printer Object Same - {0} ", firstPrinterObject.Equals(thirdPrinterObject) ? "Yes" : "No");
- Console.WriteLine("Are these Second Printer Object And Third Printer Object Same - {0} ", secondPrinterObject.Equals(thirdPrinterObject) ? "Yes" : "No");
- Console.ReadLine();
- }
- privatestaticPrinter InitializePrinterObjectAndAddDocument(string instanceName, string documentName) {
- var printerObject = Printer.GetPrinterInstance(instanceName);
- printerObject.AddDocument(documentName);
- printerObject.PrintDocument();
- return printerObject;
- }
Output



harshit porwalPosted Aug 29, 2019, 8:13 AM
Code not readable