Implementing Modular Design Pattern And OOP In JavaScript

Introduction

 
JavaScript and HTML are well-known languages for web application development, and as a web developer, it’s been a long time I have been working with these two languages. 
 
As a web application architect and developer, we have to take care of both server and client-side programming languages. I have worked with a lot of web applications/websites where I was involved in design and development. You may be aware of there are a lot of OOPS practices and principles which you have been implementing in your application in order to deliver successful projects
 
There are SOLID principles and well-known design patterns. I have seen and implemented a few of them in my practice on Server Side programming (mostly C#), but I found a lack of this principle and patterns in client-side programming languages like JavaScript.
 
However, it’s been a while when we got good frameworks for client-side development, and it’s worth to mention JQuery, Backbone, Ember, and AngularJS which are open source and come up with a web established framework to deliver rich client application.
 
In most of the cases, I have seen when the time comes to write some client-side code using JavaScript or JQuery, most of us write all the JavaScript functions and variables in the same HTML/cshtml/aspx/jsp/php document where those are required. For example:
 
Here is a function to perform client-side validation for age,
  1. function validateAge()       
  2. {      
  3.     var age = parseInt($('#age').val());      
  4.     if (age < 20)       
  5.     {      
  6.         $('#error').html('Please enter a valid age');      
  7.     }      
  8. }     
And generally, we attach this in the submit button or input element and perform age validation on change. And when our application moves towards complexity we pollute global or window scope using this approach. In this article, I am going to explain how we can create namespaces or modules, and further, we will implement generic methods in those modules. Since JavaScript doesn’t have any concept like a class in which we are familiar with many OOPS languages but it can be achieved using a constructor function.
 
Let’s have a look into the above function which is being used to verify age:
 
Problem: We cannot re-use this function in other views/pages. So wherever we will require age, the validation we need to copy and paste.
 
Solution: Create a separate module.
 
Create a module for your application,
  1. var validationModule =         
  2.     {        
  3.     config:         
  4.       {        
  5.         ApplicationName: 'Default',        
  6.         validationEnabled: true        
  7.     },        
  8.     validateAge: function(element)         
  9.       {        
  10.         if (this.config.validationEnabled == true)         
  11.         {        
  12.             return (parseInt($(element).val()) > 20);        
  13.         } else         
  14.         {        
  15.             throw 'Validations are disabled';        
  16.         }        
  17.     }        
  18. };   
Now you are free to use this anywhere in your application in any way you want to use.
 
If you want to use this inside script you can use it like:
  1. var myApp= validationModule;        
  2. var isValidAge = myApp. validateAge($('#age'));    
Problem: Whenever we declare any variable in JavaScript there might be two cases: 
  1. Global variable 
    1. var VERSION=1.2.0; 
  2. Private variable
    1. function getDateOfBirth()      
    2. {      
    3.     // private variable      
    4.     var age = parseInt($('#age').val());      
    5.     var dob = (new Date().getFullYear()) - age;      
    6.     return dob;      
    7. }     
There is a misconception about the scope of variable
  1. var config =     
  2. {    
  3.     user: 'Anupam'    
  4. }    
  5.     
  6. function VerifyUser()    
  7. {    
  8.     
  9.     if (config.user == 'Anupam')    
  10.     {    
  11.         var text = 'hi ' + config.user;    
  12.     } else    
  13.     {    
  14.     
  15.         // invalid user    
  16.     
  17.     }    
  18.     // text has scope beyond if block     
  19.     console.log(text);    
  20. }    
  21. VerifyUser();    
  22. console.log(text); // now undefined   
Tip: If we define any variable without using var keyword anywhere in JavaScript it gets injected in the global scope. For example, x=’test’;
 
Try to run this example in your document and see the output. Since we defined variable text inside if block but this is still available after the block.
 
While implementing modular programming in our application we can work with private members efficiently with the help of constructor function (if you are an AngularJS developer you might be aware of service, which is a very good example of constructor function).
 
Module with a constructor function and with private members
 
Here is the same example with constructor function, using which we can use private members:
  1. var validationModule = (function()                             
  2.  {    
  3.     // current scope to variable module     
  4.     var module = this;    
  5.     
  6.     // private variable    
  7.     var defaultConfig =    
  8.     {    
  9.         ApplicationName: 'Default',    
  10.         validationEnabled: true    
  11.     };    
  12.     
  13.     module.getConfig = defaultConfig;    
  14.     
  15.     module.setConfig = function(config)     
  16.     {    
  17.         defaultConfig.ApplicationName = config.ApplicationName;    
  18.         defaultConfig.validationEnabled = config.validationEnabled;    
  19.     };    
  20.     
  21.     module.validateAge = function(age)    
  22.     {    
  23.             if (defaultConfig.validationEnabled == true)    
  24.             {    
  25.                 return (parseInt(age) > 20);    
  26.             } else    
  27.             {    
  28.                 throw 'Validations are disabled';    
  29.             }    
  30.         }    
  31.         // return module    
  32.     return module;    
  33. })();   
Now using this module all the members which are module.* will be available in your application, because it is return type of our module. And you can also work with private member.
 
We can also share properties or global objects using a constructor parameter as follows.
  1. (function(window, $)    
  2.  {    
  3.     // work with global window and JQuery object here    
  4. })  
  5. (window, JQuery);   
It was a quick start to develop large applications using a modular approach so that we can handle dependencies easily in large applications. You can add events and can also extend your module using a JavaScript prototype.
 

Summary

 
I hope you have enjoyed and learned how we can work with OOP flavor in JavaScript. It would be my pleasure to answer and entertain your queries/suggestion.