In this article(series) I am going to explain, how we can implement some well known design pattern in JavaScript. Its been couple of years that JavaScript has became popular and now you can develop whole web application in JavaScript( ex: nodejs).
As we all know its easy to write such a BAD CODE in JavaScript since its interpreted and loosely typed language. I am going to introduce some well known design pattern in order to maintain scalability in large JavaScript application.
Lets start with a brief definition of design pattern.
What are Design patterns
Design patterns are the proven solutions for common software design (or coding) problems. It is quite useful to reuse the solution you have written before. In the same way, you can use design patterns to solve coding problems instead of writing the same from scratch.
If you are using any Object Oriented Programming Language, the design patterns are very helpful as they can be reused in your existing solution and you can even communicate your solution with the other developers.
It’s very important to know the design patterns, but it’s not required to use those in every situation (which is known as pattern abuse).
Design patterns are discussed in detail in GoF book named “Design Patterns Elements of Reusable Object Oriented Software”.
There are several examples of design patterns using different Object Oriented Programming Languages. This series is dedicated to the design patterns using JavaScript. In this series, I am going to discuss Creational Design Pattern.
Design pattern is categorized in three sections, namely Creational, Structural, and Behavioral. Creational design pattern describes the way to create (instantiate) an object. This category of design pattern focuses on handling the object's creation mechanism, where the created object is suitable for the current situation. In this category, we control the object creation process.
There are four well known design patterns that come under this category as follows,
- Factory Method
- Prototype
- Builder
- Singleton
In this article, I am going to discuss Factory Method design pattern and how we can use the same in JavaScript.
I recommend visiting a series of articles, written by Sumit Jolly on JavaScript, if you are new to JavaScript.
In this article we will understand Factory Pattern using JavaScript.
Factory Method
In this pattern, JavaScript Object has a method which is responsible to instantiate another object. If the object is simple or doesn’t have any complex linked objects, factory pattern is not required. If you have complex JavaScript Object(s) to initialize (family of objects), you should go for Factory Method pattern.
In short, Factory Pattern makes it easy to create the new object(s).
As the name says, factory is an entity which produces some similar kind of product (object in our oops).
Using this pattern, we encapsulate object creation logic inside the Factory and it does not require using Constructor explicitly.
Using Code
To understand Factory pattern, a great example is JavaScript API function document.createElement(), which is a function to create any html element e.g.
document.createElement(‘div’) will create a div element in DOM and return the instance of the newly created object.
Let’s have a typical example of a computer hardware shop, which has a motherboard, RAM, battery etc.
For this example, I am using node environment (I bet if you are a JavaScript developer, you must have it), but you can try these examples in any Browser.
Or you can download
NodeJS.
Note
If you are running this example in the Browser, you need to include require.js, which is used to include the modules in the node Application.
Here is my hardware file, which has three types of hardware used in a computer/laptop.
- module.exports.motherboard= function (cpuType, architecture) {
- this.name ="Motherboard";
- this.type=cpuType;
- this.architecture=architecture;
-
- this.getSpecification=function () {
- console.log("specification(s) = name :"+this.name+", Cpu Type: "+this.type+", Architecture="+this.architecture);
- };
- };
-
- module.exports.ram=function (ramType, memory) {
- this.name ="Ram";
- this.type=ramType;
- this.momory= memory;
-
- this.getSpecification=function () {
- console.log("specification(s) = name :"+this.name+", Ram Type: "+this.type+", Memory="+this.momory);
- };
- };
-
-
- module.exports.battery=function (type, cells) {
- this.name ="Battery";
- this.type=type;
- this.cells=cells;
-
- this.getSpecification=function () {
- console.log("specification(s) = name :"+this.name+", Type: "+this.type+", Cells="+this.cells);
- };
- };
In order to use these objects in my UI, the following is the code used typically:
-
- var hardware = require('./hardwares');
-
-
- var ram = new hardware.ram("DDR3","4GB");
- console.log(ram.getSpecification());
-
- var motherboard = new hardware.motherboard("i5","64 Bit");
- console.log(motherboard.getSpecification());
As you can see, each time you will need to add new hardware you will have to modify your code to instantiate the object, using a new keyword along with the Constructor parameters.
Since we are having limited Constructor arguments at this time, these parameters can be complex configuration.
Using Factory Pattern
Now, we will centralize the object creation, using Factory pattern, so that we can minimize the changes in our code.
Here is the Factory Constructor function, which is used to centralize the object creation process along with the default Constructor arguments/configuration, as shown below:
- var hardwareTypes = require('./hardwares');
-
- var computerHardwareFactory = function(){
-
- var hardwares =[
- { type : "motherboard", hardware: new hardwareTypes.motherboard("i5","64 Bit")},
- {type: "ram", hardware: new hardwareTypes.ram("DDR3","4GB")},
- {type:"battery", hardware: new hardwareTypes.battery("medium",6)}
- ];
-
- for(var i in hardwares){
-
- this[hardwares[i].type]= this[hardwares[i].type]|| hardwares[i].hardware;
- }
-
- };
-
-
- module.exports = new computerHardwareFactory();
I have used comments for better understanding. Feel free to ask your queries, if anything is not clear in the code.
Using Factory class, we are using the following code to use the hardware instances to work with, as shown below:
- var hardwareFactory = require('./computerHardwareFactory');
-
- var ram = hardwareFactory.ram;
- var motherboard=hardwareFactory.motherboard;
-
- ram.getSpecification();
- motherboard.getSpecification();
Now, when you add new hardware, you just have to add the same in the factory and you can use that instance again and again,
using hardwareFactory.[hardwareName].
Therefore, hardwareFactory simplified the object creation process and gave us a handy object to work with.
To run the code given above, you just need to download the attached files and open command prompt > navigate to folder> type node index.js (file to run).
In my next article, I will try to cover next pattern- Prototype. Meanwhile, you can share your constructive comments and suggestion.