In software development programming languages Modules are an integral unit of
An enterprise-level software application may contain several different modules, and each module serves unique and separate business operations.Modules make a programmer’s job easy by allowing the programmer to focus on only one area of the functionality of the software application. Modules are typically incorporated into the program through interfaces.
In a previous post I discussed ,
Fibonacci.js module to return a Fibonacci sequence of numbers.
Fibonacci.js is an example of the
Traditional Object Oriented programming languages like Java, C#, C++ , Python etc, make use of the
Class object to create self contained and decoupled units of code, which can be treated as block boxes of functionality which can be enhanced, added and removed according to requirements.
A Module can be considered as similar to a
Singleton Class in an object oriented language.
In a Module, all the variables defined are visible only in the module. Methods in a module have scope and access to the shared private data and private methods. Thus implementing a
closure, as discussed later
- Immediate functions
- Private and public methods
Using the module pattern you can with very little code, effectively namespace related methods and properties, organise and create privacy for entire modules of code and minimise global scope pollution.
closure principle providing the control of privacy in your methods so that third party applications or modules cannot access data in variables or overwrite it.
What is a closure ?
global scope except variables that are declared within a function using the
Variables declared in a function have access to the global scope and every other scope above the function that you are in. In other words an inner function has access to the variables that are within the function that wraps it.
A closure is the combination of a function and the lexical environment within which that function was declared.
What we have done here is declare a function, which essentially calls itself immediately. This creates a new scope in which we can wrap all our function logic in, and we return only that parts we need.
After we have created a new
scope , we can create a namespace for our anonymous Module. In my example I will be creating a Module to return a Fibonacci sequence of numbers, so I will create a Fibonacci namespace.
- Reduces clutter with the global namespace
- suports private data
- Cleaner code for developers
- Enables unit testability of code
- private methods are not accessible outside the module
- Private methods are not extensible
Typically Modules will use
return and return an
object to the Module, which will enable methods to bound to the object and accessible from the modules namespace. Essentially we return an
Object Literal and we can call them exactly the same way.
Locally scoped object literal
When developing a module, you may want some means to identify when you’re calling external public methods and internal private methods. This can be really handy when you’re developing large Modules i.e. Modules that that exceed 100 lines of code.
You may want to identify private method without have to check the return statement. In this instance we can create a locally scoped namespace within our Module.
Stacked locally scope Object Literal
Virtually the same as the previous example, but it uses more of traditional single object literal notation:
Using a technique called the Revealing Module Pattern which is an enhanced design pattern to ensure all methods and variables are kept private until they are explicitly exposed
Revealing Module Pattern
The Revealing Module Pattern is an enhanced design pattern to ensure all methods and variables are kept private until they are explicitly exposed.
The methods are usually exposed through an object literal returned by the closure from which it’s defined.
Advantages of the Revealing Module Pattern
- Cleaner Approach
- Support for private data
- Reduces global noise
- Localization of functions and variables through closures
- concise syntax
- Explicitly defined public methods and variables
ES 6 Modules
The patterns provided isolation to a certain degree but unfortunately do not declare dependencies.
The main concept in CommonJS modules is a function called
require. Calling this method with a module name makes sure the module is loaded and returns and its interface and because the loader wraps the module code in a function the module automatically get their own scope.
require is used to import modules enabling you to include modules in your programs. You can add built-in core Node.js modules, community-based modules (
node_modules), and local modules.
- ES6 modules share a compact syntax
- Support cyclic dependencies
- Designed for asynchronous loading
- Static structures to help with static checking, optimized imports and dead code elimination.
Building on the Examples in the previous sections we can now redevelop our Genie module using the ES6 module approach.