Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Understanding the JavaScript revealing module pattern

Posted: September 12, 2015
Written by: Saints At Play
Category: Javascript

As our JavaScript applications start to become more complex and demanding it makes sense to turn towards using specific design patterns as a way of managing those needs. In this particular article we're going to take a look at one particular design pattern: the revealing module.

Wait a minute...what's a design pattern?

A design pattern is simply an agreed solution for a particular coding problem or set of problems that can help with the following:

  1. Is re-usable
  2. Is proven to work
  3. Provides an agreed structure and vocabulary
  4. Helps avoid code repetition
  5. Allows developers to compose elements and relationships between elements within their code more efficiently

The architect Christopher Alexander is credited with developing design patterns in the late 1970's and the term was later applied to software design in the 1990's by the Gang of Four (Erich Gamma, John Vlissides, Ralph Johnson and Richard Helm).

A design pattern can fall into one or more of the following categories:

  • Creational (handles/controls object creation)
  • Structural (handles the composition of and relationship between objects)
  • Behavioural (handles the communication between objects in a system)

Some of the different types of design patterns commonly used in software design (regardless of the programming language) are as follows:

There are, however, many different design patterns but, for the purpose of this article, we are only interested in the revealing module pattern and how that applies to developing JavaScript applications.

The revealing module pattern

Developed by Christian Heilmann as an alternative to the Module design pattern the revealing module (or revelation pattern as it is sometimes called) can be considered both a creational and structural design pattern that offers the following benefits:

  1. Allows emulation of private access modifiers in JavaScript
  2. Provides a consistent and clean separation between private and public modifiers
  3. Avoids global namespace pollution through localisation of variables and methods via closures
  4. Provides a consistent structure for code
  5. Highly readable solution for developing code
  6. Self-invoking - does NOT require a constructor to be initialised

Let's go over some of these benefits in a little more detail just to understand exactly what this particular design pattern offers and why, as a developer, you really should consider using it.

To do this we'd probably be best served by looking at an example of the revealing module pattern in action:

var MANAGER = (function()
{

  var _privateMethodOne  =  function()
  {
     _privateMethodTwo();
  },



  _privateMethodTwo      =  function()
  {
     console.log('Hello!');
  };


  return {
    publicMethodOne      :  _privateMethodOne
  }

})();

To use this class in our scripts we would simply call the following (after the above has been loaded into our page):

MANAGER.publicMethodOne();

//Which prints out the following to the browser console
Hello! 

Okay, let's break down the above class according to the benefits of using this design pattern that we listed earlier.

1. Allows emulation of private access modifiers in JavaScript

In our sample class the following methods are defined locally, through the var statement, and are not able to be accessed outside of the class:

var _privateMethodOne  =  function()
  {
     _privateMethodTwo();
  },


  _privateMethodTwo      =  function()
  {
     console.log('Hello!');
  };

JavaScript in its current incarnation does not support private access modifiers like Java or PHP do so, in the above code, we are actually emulating private data. This is done through the use of closures (_privateMethodOne and _privateMethodTwo) contained within the parent function wrapper. If you're not familiar with what a closure is we'll cover these in a later section.

In the above snippet, the use of the underscore that prefixes each method is a coding convention used to indicate that the method is deemed private and should not be publicly accessible.

2. Provides a consistent and clean separation between private and public modifiers

As described in the previous section the following methods are closures and inaccessible outside of the class:

  • _privateMethodOne
  • _privateMethodTwo

To make these methods available in the global scope we need to make them public and return them like so:

return {
    publicMethodOne      :  _privateMethodOne
  }

This class structure provides a clean separation between private and public members making this design pattern easy to understand and also to implement.

3. Avoids global namespace pollution

(function()
{

})();

The above snippet displays the parent function wrapper (known as an Immediately Invoking Function Expression or IIFE - we'll cover this in a later section) allowing for the creation of what are called closures.

A closure is an inner function contained within a parent function that has access to variables and methods in the parent function.

If we look at our original revealing module class structure this will become a little clearer:

var MANAGER = (function()
{

  var _privateMethodOne  =  function()
  {
     _privateMethodTwo();
  },



  _privateMethodTwo      =  function()
  {
     console.log('Hello!');
  };


  return {
    publicMethodOne      :  _privateMethodOne
  }

})();

The parent function would be the Immediately Invoking Function Expression associated with the global variable MANAGER and the inner functions would be _privateMethodOne and _privateMethodTwo.

We notice that _privateMethodOne can call, and make use of, a method in the parent function called _parentMethodTwo - making this a perfect example of a closure.

Both of these methods would be inaccessible outside of the scope of the Immediately Invoking Function Expression unless they are explicitly declared as public which happens at this point in the class:

return {
  publicMethodOne      :  _privateMethodOne
}

The revealing module pattern helps avoid global namespace pollution as its variables and methods are localised to the Immediately Invoking Function Expression and are not able to be accessed externally UNLESS they are made explicitly public.

4. Provides a consistent structure

Based on what has been discussed earlier, this should be a no brainer.

The separation of private and public members, use of closures and Immediately Invoking Function Expressions allows for a reliable, well-defined code structure that can be reused in different classes and across different projects without the need for structural re-factoring.

5. Highly readable solution for developing code

The clear, well defined structure of the revealing module pattern makes developing classes and methods that are easy to understand for teams of developers working on the same project.

Best practice should always involve self-explanatory naming of your classes, variables & methods (I.e. _networkDetectionAndParsing, _formValidationRoutine etc), clear and consistent formatting of the code (I.e. braces dropped onto separate lines, consistent number of carriage returns between methods, stepped indentation of code etc) and clear documentation of each class, variable and method using the YUIDoc or JSDoc standards.

6. Self-invoking - does NOT require a constructor to be initialised

The revealing module pattern uses what is known as an Immediately Invoking Function Expression (IIFE) which means that the class is able to be self-invoked without having to be explicitly initialised.

We explicitly name our IIFE so as to help with debugging and organising our code more effectively:

var MANAGER = (function()
{
 // All code inside here
})();

As this class has been self-invoked we can directly call its methods without having to initialise it like so:

MANAGER.publicMethodExecutedHere();

The class is able to self-execute due to the trailing parentheses at the end of the function expression:

var MANAGER = (function()
{
 // All code inside here
})(); // Parentheses automatically executes function

Accessing global objects

Another benefit of the revealing module pattern is that we can pass references to global objects to our class as parameters in our function expression:

var MANAGER = (function(w, $)
{
 // All code inside here
})(window, jQuery);

This will then allow our class to access the methods of these objects in its own local context, similar to dependency injection in Laravel or AngularJS, which is a very powerful way of accessing services from different classes, libraries and plug-ins without overwriting these or polluting the global namespace.

Namespaces and the revealing module pattern

As JavaScript applications often require multiple classes to cater for the complexity and different types of functionality required it makes sense to use namespaces to organise our code more effectively. The revealing module pattern can easily be adapted to use a namespace:

var MYNS        = MYNS || {};
MYNS.Manager = (function()
{
  // Methods inside here
})();

This would then call methods in the following manner:

MYNS.Manager.publicMethodOne();

Sounds great but...

What are the drawbacks to using this design pattern?

Depending on your perspective you may find the following to be disadvantages of this particular solution:

  • Inability to access private members (this might be an issue with unit testing for example although it can be argued that if you need to test a private variable/method then it should probably be public anyway)
  • Difficult to fix bugs with public methods if they are referred to as different methods privately
  • Lack of understanding of closures could lead less-experienced developers to struggle with this pattern
  • Not as memory efficient as prototypical inheritance

Wrapping it up

The revealing module pattern provides JavaScript developers with a robust, scalable structure for architecting their classes, clean separation between private and public members, the ability to access global objects locally by reference, is highly readable and self-invoking making this a highly desirable solution for code development, organisation and management.

« Return to Posts

Comments

There are no comments

Posting comments after three months has been disabled.