Thursday, October 4, 2012

Practical example of the Revealing Module Pattern in JavaScript

One of my friends, Russell Durham, created an excellent blog post on the revealing module pattern in javascript. I asked him if I could replicate this on my blog. The original post is JavaScript Revealing Module Pattern

The revealing module pattern is one of several patterns that allow you to create namespaces within your javascript while also providing a method of creating public and private functions. In general, anything you write in a script block is considered to be in the global namespace so any other javascript on the page will have access to it.
 
function globalOne() {
 //random code here
};

function globalTwo() {
 globalOne();
}; 
I’ve seen a lot of developers that actually write javascript this way and while it may still work it is not a good practice. When writing your class libraries or other server side code you wouldn’t (at least I hope you wouldn’t) expose every function within the library. Some functions exist only to help the public functions complete their task and have no business being called outside of the library. The same can apply to javascript functions. Let’s say you have an online shopping site and while in the checkout process the user can update the quantity of what’s in the cart as well as the shipping method and this in turn updates the total. Using the method above of keeping everything in the global namespace our javascript would look something like this:
function updateQuantity(newQuantity) {
 //code to update the quantity
 updatePrice(newPrice);
};

function updateShipping(newShippingMethod) {
 //code to update the shipping method
 updatePrice(newPrice);
};

function updatePrice(newPrice) {
 //code to update the price
}; 
Functionally, this code is correct. It meets the requirements and everything is good. However, now everyone has access the the updatePrice function. I’m not sure about everyone else but I sure don’t want my users to be able to update the price whenever they feel like it. I want a little more control over how and when that function is called. This is where the revealing module pattern comes in. The pattern is pretty simple:
var myObject = (function() {

 var publicFunction = function() {
  //do something public
 };

 var privateFunction = function() {
  //do something private
 }

 return {
  doSomething: publicFunction
 }

})();
The first thing you’ll notice is that we create an object to place the functions inside of. Doing this removes the functions from the global namespace and makes the only visible within the scope of the object (making them all private). To make a function public you need to return the function from within the object which is done on line 11. Notice how left of the “:’” is “doSomething” while to the right is the name of our function. Changing the value on the left side allows us to change the name of the public facing function. So now, instead of calling:
myObject.publicFunction();  
We can call it like this:
myObject.doSomething();  
In this case doSomething is mapped to publicFunction. Now that we’ve seen the pattern, let’s apply it to our earlier example with the shopping cart.
var cart = (function() {

 function updateQuantity(newQuantity) {
  //code to update the quantity
  updatePrice(newPrice);
 };

 function updateShipping(newShippingMethod) {
  //code to update the shipping method
  updatePrice(newPrice);
 };

 function updatePrice(newPrice) {
  //code to update the price
 };

 return {
  updateQuantity: updateQuantity,
  updateShipping: updateShipping
 }

})();
That’s much better. Now all the functions are removed from the global scope and placed inside of our new cart object. Only updateQuantity and updateShipping are returned which means that updatePrice is now a private method that can not be accessed outside of the cart object. To call our new functions is a simple as:
cart.updateQuantity(5);
cart.updateShipping('overnight');  
However, if we try and call cart.updatePrice(5.00) we’ll have an exception thrown since cart.updatePrice does not exist. As I mentioned before there are other patterns that can be used to accomplish the same thing but the revealing module pattern is the one I find myself using the most often. It is easy to read, easy to use and makes exposing public members simple.

No comments:

Post a Comment