Saturday, October 24, 2015

Javascript Design Patterns - Singleton with Closure

Singleton Pattern: 
Singleton Pattern is a design pattern that restricts a instantiation of a class to single object. Only one object will service all the action across the system.

Problem in Javascript with Singleton Pattern
It is pretty easy to implement singleton pattern in normal object oriented languages. You can make the constructor of the class to private and you can expose static method to return the instance of the object. Your static  method can take care of single object creation.

But the Javascript world is completely different. There are couple of issues in implementing Singleton pattern in javascript

  • Here variable  scope can be global or functional. It is not possible to have "private" member variable by default
  • It is not possible to  have "Private" function to hide from outside application. 
In order to overcome the problem of handling "private" function/variable, Closure is useful.


Closures:
Closures are the functions which can reference/remember the variables that are created in the environemnt on which it is created. While the function is created, it gets the reference to the variable. When ever you call the function from outside, it will hold the reference of the variable and will have the ability to update/call the variables/functions.


How Singleton and Closures Goes Hand in Hand
As you see from the definition of Closure, a function can remember the reference of the variable/function that was created in their environment. To simplify this, outer function can refer the variable with its scope . So when the function is instantiated, variable will be created but the scope will alive even after returning the method. But inner function will have access to the variable. It will act as "Private variable" scenario.

Practical Scenarios
Problem with most of the developers is that they read the concepts of the design pattern but they do not know where to apply the concepts. Let's see some of the practical  scenario where you can use Singleton design pattern in with usage.


  1. Global Cache maintenance: Assume that you are using Single Page Application (SPA) and handling multiple  pages using AJAX request. If you have some application level definition data or  common data such as State of a country, cities etc , they  can be used in multiple places. It is unnecessary to load multiple time. If you create global cache object in browser, you can store the data. When you first time request data, browser should request application and get the data and should cache it. Next time, it should return the data from cache. So Only one instances should be maintained. Singleton pattern will be useful to get handle cache
  2. Logging: Normally Javascript logging can be implemented by various frameworks like log4javascript. you use singleton pattern to create single logger and can encapulate the logger object and expose the logging related functionalities alone in other places
Logging Example

Let's see how Singleton design pattern works with closure in a practical use case. Assume that the application uses Log4Javacript library for logging Client side javascript errors into Server. Here is the sample code which uses all the concepts that was mentioned before to achieve the results elegantly.

 Client.Logger = (function () {
       //Private Variable
        var serverLogger;
       //Private Member
        function setServerLogger() {
            //Logic to create Log4javascript object creation 
            if (typeof (serverLoggeer) != 'undefined') return serverLogger;
            serverLogger= log4javascript.getDefaultLogger();
             var baseurl = 'http://localhost/app';
            var callAppender = new log4javascript.AjaxAppender(baseurl + "ClientLogger/ClientLogMessageListener.php/");
           
            serverLogger.addAppender(callAppender);

           
        }
    

        return {            //public exposed methods
            debug: function (msg) {

                if (!serverLogger) {
                    setServerLogger();
                }
                
                serverLogger.debug(msg);
              
            },
            error: function (msg) {
               
                   if (!serverLogger) {
                    setServerLogger();
                }
               
                    serverLogger.error(msg);
                }
            }
            }

        };
    } ());

   window.onerror = function (msg, url, line) {
    
        Client.Logger.warn(msg );
    };

Anatomy of Code

  • In the above code, Serverlogger and Setserverlogger are the private members.
  • Serverlogger is the Log4Javascript object. We want to create single object and that obejct has to be shared accross application (Singleton object)
  • When the Client.logger instantiates, it creates method such as warn and error method. Durng the creation of method, it has the access to the outside variable serverlogger and method setserverloggermethod.
  • From through out the Application code, warn and error method can be access by calling client.logger.warn('test') and client.logger.error('error') methods to do the logging.
  • serverlogger.warn() and serverlogger.error() are server methods which update the details in log file/database.
Happy Coding!