Sorry, you need to enable JavaScript to visit this website.

Module Pattern – structure your JavaScript as modules

Module Pattern – structure your JavaScript as modules
November 17, 2017

UI developers are already using patterns in day to day scripts either knowingly or unknowingly. So how effectively can it be used, when we know more about patterns? I am about to take you through the module pattern and its usages, so that we can use it effectively in our scripts.

Let us take an example of a pattern we often use. Consider a scenario where we need to select all elements in the page with class ‘selected’. There are number of ways to do it using native feature like getElementsByClassName(), querySelectorAll(). Next, we need to figure out which of the solutions/JavaScript patterns address our problem exactly, whereas, if we are using jQuery it simply opts the most optimal approach to selecting the elements using the façade pattern. Although native features can solve the above problem, the effort involved by jQuery’s facade pattern can offer real value.

JavaScript patterns are reusable solution that can be applied to a commonly occurring problem. These design patterns are advanced object-oriented solutions to commonly occurring software problems

Module pattern helps to use object in a beneficial way and to keep a piece of code independent.

Module Design Pattern

Module design pattern is very useful for many reasons. Its main reason is for using object in a beneficial way and keeping a piece of code independent of the other code or simply put, scoping.

var counter = ( function () {
}) ();

The above code defines a function counter and calls it immediately (Immediately-Invoked-Function-Expressions), which creates a new scope and wraps all logic inside them. Then we can expose only parts of code required to global scope, leaving the remaining parts of the code private.

var counter = ( function () {
// declare private variables and / or functions
var privateCount = function () {};
var obj = {
method = function () {}
}
// declare public variables and / or functions
return obj
}) ();

We declare private variables and functions even before we return objects. Private variables cannot be accessible outside closure because it is not in the same scope.

Revealing Module Pattern

The purpose is to maintain encapsulation and reveal certain variables, methods, arrays and objects returned in an object literal. The direct implementation looks like:

var Module = ( function () {
// locally scoped variables, objects, method
var myObject = {};
var _privateVariable = "Hi!"
var _privateMethod = function () {
console.log("Module says "+_privateVariable);
};
var publicMethod = function () {
};
return {
publicMethod: publicMethod
};
}) ();

Now that is private, we can call it inside a public method to access them.

var publicMethod = function () {
_privateMethod()
};

Though we can access the private method / variable through code, we cannot access them directly.
Module.publicMethod(); // Module says Hi!
Module._privateMethod(); // Error: MyModule._privateMethod is not a function
Module._privateVariable; // undefined

In the above example _privateVariable are accessible within the module, outside the module _privateVariable unable to access. Likewise for _privateMethod(). Now we can decide which method/variable to reference in global scope and which to be within our module.

Module Augmentation

When we work on a very large project it is always better to separate the code into multiple files OR Modules. We can extend the module we created to another module and add method, variable, object etc to the original module.

Let’s consider our module example above, object for it would look like this

console.log(Module);
Object { publicMethod: function }

Now we can add a new public method anotherPublicMethod through module extension inside SecondModule and have scoping

var SecondModule = ( function (Module) {
Module.anotherPublicMethod = function () {
// anotherPublicMethod!
};
return Module;
}) (Module || {});

In the above example Module is passed into SecondModule and a method (anotherPublicMethod) is added and returned. After which if we check the object of the Module anotherPublicMethod would be added

console.log(Module);
Object { publicMethod: function, anotherPublicMethod: function }

In the SecondModule we have passed Module || {}. This is to avoid error, in case Module is undefined. If Module is undefined, it would initiate a new Object and bind anotherPublicMethod method.

Benefits

Scoping becomes very easy and structured, i.e., we can have our own private functions and variables which can be referenced only within our module and which can be referenced globally.

As we can have a number of private functions within the module, code maintainability becomes easy. We can add, replace, or delete any code accordingly.

As pointed out earlier, we should always look to start by identifying the solution/JavaScript patterns that addresses our challenge. A good understanding about JavaScript patterns, which helps us to choose the correct pattern for our problem, will be a great help in this direction.

Reference:

https://addyosmani.com/resources/essentialjsdesignpatterns/book/

http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

More from Johnson De Sathya Leo