alt text
Benjamin Thomson
Web & UX Designer

Drink A Coffee With Me Today

Loading...
Success!
Error!

Follow On Instagram

Mayank Gupta (+91-9711083089)
Menu
Close

Module Pattern in JavaScript

Module pattern is one of the most common JavaScript Design Pattern. It keeps the design very simple and easy to read and use.

We do not have repetative use of "this" and "Prototype" keywords, hence creating less confusion.


Module Pattern offer us following Benefits:

1) Module Pattern enables user to wrap public, private methods/variables into a single entity
2) Using Module Pattern we can exposing only the Public Members outside of Module.
3) Provides us with the Object Oriented feature of Encapsulation


Why Modules Pattern are Required

We shall require Modules to be created inside our function in order to ensure the following:


1) Maintainability:

Set of all related functionalities and properties can be enclosed inside a single module. By definition, a module is self-contained. A well-designed module aims to lessen the dependencies on other parts of the codebase as much as possible, so that it can grow and improve independently. Updating a single module is much easier when the module is decoupled from other pieces of code.


2) Namespacing:

Modules ensure that the common problem of Namespace Pollution can be avoided. If every function is added to the global namespace it may pollute the global scope.

Example if we have two entities: Employee and Manager and each of the entity require a function calculateSalary , in this case if we add 2 function with the same name to the global scope, one shall be shadowed. In order to prevent such situations application shall define different namespace for both the entities Employee and Maanager and shall all the related features to the corresponding Namespace.


3) Reusability:

The modules hence defined shall contain reusable code. The Modules shall expose certain set to functionalities and properties to the outer scope which can be reused at several places in the code.



IIFE (Immediately Invokable function Expressions)

In order to understand about the module pattern, we need to first understand about function Expressions and IIFE (Immediately Invokable Function Expression). Here is a small implementation of IIFE


(function(){

  alert("Function does not start with keyword function");

})();

This is a self invoking function expressions. IIFEs are executed by themselves. When it is encountered inside a code, a sepecate function scope is created. IIFE can execute like any other function, but the difference is that IIFEs are self invoking functions.

For more details and implementation details on IIFE, please refer to following: IIFE Design Pattern


Module Pattern and IIFE

Module Pattern make use of IIFE for its implementation.


Implementation Ideology of Module Pattern:

1. Application shall create an anonymous function.

2. This anonymous function is self invoked. Here we are referencing to an IIFE.

3. An IIFE shall create a seperate scope and a private enclosure where user shall define function and variables.

4. The idea is to then return set of variables and function that are needed to be exposed to outside world.


In short, the basic requirement of Module pattern is to wrap all the functions and variable is an anonymous function and return only the required set of variables and functions from the anonymous function. We execute this function expression which returns an object containing all the public members as its properties. Now this returned Object shall contain set of reusable properties and functions.


Module Pattern Implementation

Lets start implementation of a Module Pattern, step by step. First lets create an anonymous function without any further implementation. The below code is a simple anonymous function with no implementation.


(function(){

});

The next step is to invoke this Anonymous Function Expression. Anonymous function expression along with self invokation feature constitutes an IIFE. So the next step is to create an IIFE ie Self invoke and anonymous function.


In the below code we can see that the anonymous function is invoked using () at the end. This is a simple IIFE Design Pattern.


(function(){

})();

The next step is to initialize a set of functionalities and variable inside the IIFE.

So lets create a function for an Employee which contains name, age, salary field along with the functionality to calculate bonus and net salary. In the below code we created variables name, salary and also created functions like netSalary and calculateBonus.


(function(){

  var name = "Mayank";
  var salary = 0;
  var tax = 0;

  function setDetails(name, salary, tax) {
    name = name;
    salary = salary;
    tax = tax;
  };


  function getDetails(name, salary, tax) {
    console.log(name + salary + tax);
  };

  function calculateBonus() {
    return salary * .1;
  }

  function netSalary() {
    return salary + (salary * .14);
  }

})();

In the above code we have already created few variables and functions.

The next step is to expose the features (variables and functions) to the user using a return keyword.

Return shall expose the variable and functions that are required by external enviroment. We shall be exposing the functions and variables required outside this function scope.


Now lets assume that the user need to see the name of the Employee along with functionality to set the User, get the user and calculate the Bonus and Net Salary. The code below shall expose the following variables and functions using a return keyword. The returned Object shall be assigned to a variable.


var Employee = (function(){

  var name = "Mayank";
  var salary = 0;
  var tax = 0;

  function setDetails(name, salary, tax) {
    name = name;
    salary = salary;
    tax = tax;
  };


  function getDetails(name, salary, tax) {
    console.log(name + salary + tax);
  };

  function calculateBonus() {
    return salary * .1;
  }

  function netSalary() {
    return salary + (salary * .14);
  }

  return {
    name: name,
    getDetails: getDetails,
    setDetails: setDetails,
    calculateBonus: calculateBonus,
    netSalary: netSalary
  }

})();

The above code uses the return keyword, this signify that the variables and functions specified inside the return statement shall be exposed to the outer scope and shall be refered by object Employee . So now the user can access the following functionalities and functions:

1. Employee.name

2. Employee.netSalary()

3. Employee.calculateBonus()

4. Employee.getDetails()

5. Employee.setDetails()

Only following set of variables and functions are available outside the function Expression. The IIFE shall return the specified properties and functions to be used outside the scope.


Other variables and functionalities that are not exposed using return will be a part of private variables. The outer scope cannot access the private variables diirectly but the public function can access the private variables.Lets look for these details.


Private Variables in Module Pattern

We can create Private Variables using Module Pattern.

This shall enable us to cater the OOPS concept of Abstraction.

Variables that are not returned by the anonymous function is a part of private variable declaration of the Object. In the code below we are trying to access the salary of the Employee Object. The salary variable exist inside the closure as a part of private variable. We cannot access any variable or property that is not a part of return statement from outside.


Although we can see that the function calculateBonus tries to access the variable salary . The calculateBonus function can access the private variable salary since the vbariable salary exists inside closure created by Employee Object.


console.log(Employee.salary);

Any such access to the private variable shall not be allowed by the outer scope.


Summary

As per the discussion above, we can see that the module pattern can enable user to create private and public variables. The public properties and functionalities are a part of shared features.

We can see that the Module pattern shall enable us to

1. Create a Maintainable solution by implementing all the functionalities related to same Module at a fixed place.

2. The Module defined created a Namespace, all related functionalities defined under same namespace

3. The Employee Object returned shall be reusable.

{{Count}} Comments

{{comment.user}}

{{comment.message}}

{{comment.date.substring(0, 10)}}

Leave A Comment

;