Sitemap
Bittu Kumar

Bittu Kumar

Exploring Angular and Frontend development. Reach me here: https://topmate.io/bittu_kumar

Simplified Design pattern in JavaScript

5 min readApr 1, 2025

Design patterns are reusable solution to common problems comes in software design. They provide structured approach to write code that is more maintainable, scalable and efficient.

Press enter or click to view image in full size

So basically after learning design pattern we will have more clarity about writing code and our thought process get developed, We will see commonly used design pattern in JavaScript:

  • Constructor pattern
  • Factory pattern
  • Module pattern
  • Prototype pattern
  • Singleton pattern
  • Observer pattern
  • Proxy pattern

Constructor pattern

  • This is very common which we use for creating objects.
  • The constructor pattern is a creational design pattern used in JavaScript to create new object with similar properties and methods.
  • It involves defining a constructor function and then creating objects of similar type by calling the constructor function with new keyword.
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person("John", 25);
const person2 = new Person("Jane", 30);

person1.sayHello();
person2.sayHello();

Factory pattern

  • To understand factory pattern, we need to understand factory function in JavaScript.
  • Factory functions in JavaScript are simply functions that return objects without needing to use the new keyword.

Example:

function createPerson(name, age) {
return {
name: name,
age: age
};
}

let person1 = createPerson("John", 30);
console.log(person1);

Now lets understand factory design pattern, We can relate it from Pizza shop:

  • The Pizza Shop gives the perfect example to understand the Factory Design Pattern. Each pizza has its own ingredients and preparation process.
  • the factory function is like that magic factory. Instead of creating objects directly in your code, you ask the factory function to create them for you. The factory function knows how to create different types of objects based on what you need.
  • This makes your code easier to manage because you don’t have to deal with the details of creating each object yourself.
  • If you ever need to change how an object is created, you only have to update the factory function instead of changing every place where the object is created.
  • This makes your code more reusable, easier to maintain, and more flexible.

Code example:


// Class for Margherita Pizza
class MargheritaPizza {
constructor() {
this.type = "Margherita";
this.crust = "Thin crust";
this.cheese = "Mozzarella";
this.toppings = ["Tomato", "Basil"];
}
}

// Class for Pepperoni Pizza
class PepperoniPizza {
constructor() {
this.type = "Pepperoni";
this.crust = "Thick crust";
this.cheese = "Cheddar";
this.toppings = ["Pepperoni", "Cheese", "Tomato sauce"];
}
}

// Class for Veggie Supreme Pizza
class VeggieSupremePizza {
constructor() {
this.type = "Veggie Supreme";
this.crust = "Regular crust";
this.cheese = "Provolone";
this.toppings = ["Mushrooms", "Bell peppers", "Onions", "Olives", "Tomatoes"];
}
}


function createPizza(type){
switch(type.toLowerCase()){
case "margherita":
return new MargheritaPizza();
case "pepperoni":
return new PepperoniPizza();
case "veggie supreme":
return new VeggieSupremePizza();
default:
throw new Error("Invalid pizza type specified.");
}
}

const pizza1 = createPizza("Margherita");
const pizza2 = createPizza("PePperoni");

console.log(pizza1);
console.log(pizza2);

Module Pattern

  • The Module Pattern in JavaScript is a way to encapsulate code into independent, reusable modules.
  • It allows you to organize your code, keep variables and functions private, and expose only the necessary functionality to the outside world.

// using IIFE
var Calc= (function(){
// private functions and variables
var result= 0;
function add(a,b){
return a+b;
}
function substract(a,b){
return a-b;
}

// public functions
return {
add: function(a,b){
result= add(a,b);
},
substract: function(a,b){
result= substract(a,b);
},
getResult: function(){
return result;
}
}
})();

Calc.add(4,5);
console.log(Calc.getResult()); // 9



// Without using IIFE
var Calculator= {
result: 0,
add: function(a,b){
this.result= a+b;
},
substract: function(a,b){
this.result= a-b;
},
getResult: function(){
return this.result;
}
}

Calculator.add(1,2);
console.log(Calculator.getResult()); // 3

Prototype pattern

  • The Prototype Pattern is a design pattern in JavaScript that allows objects to inherit properties and methods from other objects, known as prototypes.
  • It promotes code reuse and helps conserve memory by allowing objects to share common properties and methods through inheritance.
// 1. using simple object   

var person = {
greet: function() {
return "Hello, my name is " + this.name;
}
};
var person1 = Object.create(person);
person1.name = "Bittu";

var person2 = Object.create(person);
person2.name = "Rajesh";

console.log(person1.greet()); // Hello, my name is Bittu
console.log(person2.greet()); // Hello, my name is Rajesh


//2. using constructor function
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
Car.prototype.displayInfo = function() {
return `This is a ${this.year} ${this.make} ${this.model}.`;
};

var car1 = new Car("Toyota", "Camry", 2020);
var car2 = new Car("Honda", "Civic", 2018);

console.log(car1.displayInfo()); // This is a 2020 Toyota Camry.
console.log(car2.displayInfo()); // This is a 2018 Honda Civic.

Singleton pattern

  • The Singleton Design Pattern ensures that only one instance of a class exists.
  • It provides a single point of access to that instance throughout the application.
  • It is used when controlling access to a shared resource.
class Singleton {
constructor() {
if (!Singleton.instance) {
this.data = [];
Singleton.instance = this;
}
return Singleton.instance;
}
addData(data) {
this.data.push(data);
}
getData() {
return this.data;
}
}

const singleton1 = new Singleton();
const singleton2 = new Singleton();

singleton1.addData("Data 1");
singleton1.addData("Data 2");

console.log(singleton1.getData()); // [ 'Data 1', 'Data 2' ]
console.log(singleton2.getData()); // [ 'Data 1', 'Data 2' ]

Observer Pattern

𝗟𝗲𝘁𝘀 𝘀𝗼𝗹𝘃𝗲 𝗼𝗻𝗲 𝗾𝘂𝗲𝘀𝘁𝗶𝗼𝗻 𝘁𝗼 𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗮𝗻𝗱 𝘄𝗲𝗹𝗹 𝘁𝗵𝗶𝘀 𝗽𝗮𝘁𝘁𝗲𝗿𝗻:
Create an observable that emits a value every second up to 15, with two observers subscribed. The first observer unsubscribes when the value reaches 5, while the second observer continues receiving values until completion.

Get Bittu Kumar’s stories in your inbox

Join Medium for free to get updates from this writer.

Many modern JavaScript frameworks use the Observer pattern under the hood. For example, RxJS in Angular makes heavy use of it for handling reactive data streams.

At the core of RxJS, observable is the important concept.
An observable represents a stream of data, while observers subscribe to these streams to receive emitted values. This design makes it easy to handle real-time updates and asynchronous events.

For any angular developers, we use Subject and behavior subject for component communication, That is nothing but follow observer design pattern.

1️⃣ Observable: Represents a stream of data that can emit values over time.
2️⃣ Observer: Listens (subscribes) to the observable and reacts when new data is emitted.

import { Observable } from 'rxjs';

// Create an observable that emits a number every second until it reaches 15.
const myObservable = new Observable(subscriber => {
let count = 1;
const intervalId = setInterval(() => {
subscriber.next(count);
if (count === 15) {
subscriber.complete();
clearInterval(intervalId);
}
count++;
}, 1000);

return () => {
console.log('Unsubscribing...');
clearInterval(intervalId);
};
});

console.log('Subscriptions started...');

const subscription1 = myObservable.subscribe({
next: (value) => {
console.log('Observer 1:', value);
if (value === 5) {
console.log('Observer 1 unsubscribing at value:', value);
subscription1.unsubscribe();
}
},
error: (err) => console.error('Observer 1 error:', err),
complete: () => console.log('Observer 1 completed!')
});

const subscription2 = myObservable.subscribe({
next: (value) => console.log('Observer 2 :', value),
error: (err) => console.error('Observer 2 an error:', err),
complete: () => console.log('Observer 2 completed!')
});

Proxy Pattern

— will publish it soon

I hope you enjoyed learning design pattern in JavaScript, There is many pattern like this.

Happy Learning. Reach me out here for any discussion: https://www.linkedin.com/in/bittukumar-web/

--

--

Bittu Kumar
Bittu Kumar

Written by Bittu Kumar

Exploring Angular and Frontend development. Reach me here: https://topmate.io/bittu_kumar