Coders Read

Learning Design Patterns  –  Javascript

Javascript web developers often interact with design patterns, even unknowingly when they develop any application. In this article we will go though some of the design patterns which are basically a reusable solutions to common problems in software design.

So What are Design Patterns?

Design patterns represent the best practices used by software developers. It teach you how to think. The main benefit of learning design patterns is that you can come up with solutions to your problems a lot faster.

These are not codes ready be used but are documented solutions to commonly occurring problems in software engineering that the programmer can use to a solution when designing an application or system. Let’s have a look at some of design patterns.

Why do we need Design Patterns ?

  • Design pattern are reusable solution that can be applied to commonly occurring problems in software engineering.
  • Solution can be given in more expressive, encapsulated & structured way.
  • When creating or maintaining solutions, Design patterns is one of the most powerful approaches to getting all engineers of your team on the same page.

1. Constructor Pattern

Being a Javascript developer we might have met with constructors at some point. These are special functions that initialize objects with specific properties and methods. The constructor method gets called whenever we create an object of a class. Here, the class represents an entity. As the name defines Constructor Pattern is a class-based pattern that uses the constructors present in the class to create specific types of objects.

function Employee(name, designation){
    this.name = name;
    this.designation = designation;
    this.describe = function(){
        console.log(`${this.name} is a ${this.designation}`);
    }
}

var emp = new Employee("Sourabh", "Software Engineer");
emp.describe();

var emp1 = new Employee("Raj", "Manager");
emp1.describe();

In the above example, JavaScript uses functions as constructors. These functions are used to instantiate objects. The constructor function Human is defined with few properties.

2. Factory Pattern

This is a type of Object Oriented pattern which follows the DRY methodology. Like the name suggests, object instances are created by using a factory to make the required object for us.

We often use this pattern in situations where we need to deal with potential problems which occur when creating objects. By calling a factory method we avoid reallocating memory for each object we create, instead a factory method does that only once when it’s called. It does not use the new keyword directly to instantiate objects, So it does not explicitly require the use of a constructor to create objects.

function carFactory() {  
    this.createCar = function(carType) {   
        let car;    
        switch(carType) {      
            case 'coupe':        
                car = new Coupe();        
                break;      
            case 'hatchback':        
                car = new Hatchback();        
                break;      
            case 'suv':        
                car = new Suv();        
                break;      
            default:        
                car = new Sedan();        
                break;    
        }    return car;  
    }
}

const Sedan = function() {  
    this.getDetails = () => {   
        console.log('Honda City');  
    }
}

const Suv = function() {  
    this.getDetails = () => {    
        console.log('Hyundai Creta');  
    }
}

const Hatchback = function() {  
    this.getDetails = () => {    
        console.log('Hyundai i20')  ;
    }
}

const Coupe = function() {  
    this.getDetails = () => {    
        console.log('Nissan GT-R');  
    }
}

const factory = new carFactory();

const car1 = factory.createCar('coupe');
car1.getDetails();

const car2 = factory.createCar();
car2.getDetails();

3. Prototype Pattern

Prototype pattern is used to instantiate the objects with some default values by making use of existing object. It lets us create clones of the existing objects. This pattern relies on the prototypal inheritance of JavaScript where the prototype object acts as a layout from which other objects inherit when instantiated through a constructor.

const car = {  
    color: 'silver',  
    start() {    
        console.log('Starting the car'); 
    },  
    stop() {    
        console.log('Stop the car');  
    }
}

// Proper prototype cloning
const myCar = Object.create(car, { 
    owner: { 
        value: 'Sourabh'
    } 
});

console.log(myCar.__proto__ === car);
car.type = 'Sedan';


console.log(myCar.type);

In prototype pattern the cloned objects are created by reference. They dont have their own separate copies. This boosts the performance and efficiency of code.

  • It can be used to remove the overhead of initializing an object.
  • It simplifies and optimizes the use case where multiple objects of the same type will have same data most of the time.

4. Singleton Pattern

Here comes my favourite design pattern. Singleton pattern is what got me excited to look more into design patterns.

This pattern ensure that a class has only one instance and provide a global point of access to it. If something tries to make another instance, it simply returns a reference to the instance that already exists.

var SingletonPattern = (function () {
    var instance;

    function createInstance() {
        var object = new Object("Instance created");
        return object;
    }
    
    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

var obj1 = SingletonPattern.getInstance();
var obj2 = SingletonPattern.getInstance();

console.log(obj1 === obj2);

Using this pattern saves the memory because objects are not created at each request, instead single instance is reused again and again. This pattern is mostly used in database and multi threaded applications.

5. Command Pattern

This is one of the most popular design patterns that people like to use, it allows developers an opportunity to issue commands from anything executing commands and delegates responsibility to different objects instead. T

  • The Command pattern aims to encapsulate method invocation or requests into a single object and gives us the ability to pass method calls around that can be executed.
  • The Command Pattern is a great pattern for architecting really clean decoupled systems. I believe it is the root pattern of Redux.

Elements to the Command Pattern :

  • Receiver: Its job is to hold our business logic and fulfil the request once command is received.
  • Command: It contains information about the action being called and its required parameters.
  • Executor: The executors job is pass the command to the receiver and call our business logic.
// Receiver
function requestInfo(model, id) {
  return `Here is ${model} with id: ${id}`;
}

function buyVehicle(model, id) {
  return `You just purchased a ${model} with id: ${id}`;
}

function arrangeViewing(model, id) {
  return `Successfully booked a viewing of ${model} (${id})`;
}
// Command
const HyundaiSalesControl = {
  buyVehicle,
  requestInfo,
  arrangeViewing
}
// Executors
function execute(receiver, command) {
  return (
    receiver[command.action] 
    && receiver[command.action](...command.params)
  );
}
// Executing commands
execute( HyundaiSalesControl, {
  action: "requestInfo", 
  params: ['Hyundai Creta, '108']
});

execute( HyundaiSalesControl, {
  action: "arrangeViewing", 
  params: ['Hyundai Creta', '108']
});

execute( HyundaiSalesControl, {
  action: "buyVehicle", 
  params: ['Hyundai Creta', '108']
});

 . . . . .

It is beneficial for JavaScript developers to use design patterns. Design patterns are frequently used in larger applications, But understand where one might be advantageous over another, comes with practice. I am too in the learning phase.

Sourabh Sinha

Add comment

Follow us

Feel free to get in touch. I love meeting interesting people and making new friends.

Any suggestions will be appreciated.