Let's know what is design pattern is type to coding practises which allow you to Write modular and optimise code and allow you to write code which is easier to understand.
The Module Pattern is a way to organize your JavaScript code so that:
-
Some data and functions are private (hidden from outside).
-
Some are public (can be accessed from outside).
-
It helps keep your code clean, secure, and modular — meaning you can manage different parts separately.
const counterModule = (function () {
// Private variable
let count = 0;
// Private function
function logCount() {
console.log("Current count:", count);
}
// Public methods
return {
increment: function () {
count++;
logCount();
},
reset: function () {
count = 0;
console.log("Counter reset!");
}
};
})();
counterModule.increment(); // Current count: 1
counterModule.increment(); // Current count: 2
counterModule.reset(); // Counter reset!
- Keeps code organized and modular
- Prevents global scope pollution
- Protects private data
- Makes debugging and maintenance easier
The Revealing Module Pattern is just an improved version of the Module Pattern. It makes the code cleaner and more readable.
let bank=(()=>{
let balance=150;
function deposit(amount){
console.log(`Depositing ${amount}`);
balance+=amount;
}
function withdraw(amount){
console.log(`Withdrawing ${amount}`);
balance-=amount;
}
function getBalance(){
console.log(`Balance is ${balance}`);
}
return {
set:deposit,
get:withdraw,
check:getBalance
}
})()
bank.set(100);
bank.get(50);
bank.check();
- Keeps code modular and secure
- Avoids global scope pollution
- Improves code readability
- A Factory Function is a function that creates and returns objects.
- Unlike a class, you don’t use new. You just call the function to get a new object.
- It’s called a “factory” because it produces objects on demand.
/ Factory Function
function createPerson(name, age) {
return {
name,
age,
greet() {
console.log(`Hi, my name is ${name} and I am ${age} years old.`);
}
};
}
// Usage
const person1 = createPerson("Alice", 25);
const person2 = createPerson("Bob", 30);
person1.greet(); // Hi, my name is Alice and I am 25 years old.
person2.greet(); // Hi, my name is Bob and I am 30 years old.
- You need multiple similar objects with the same methods.
- You want to encapsulate private data.
- You don’t need classes or new keyword.
- You want flexible object creation with dynamic data.
- The Observer Pattern is a design pattern where one object (called the subject) keeps a list of its dependents (observers) and notifies them automatically of any state changes.
- When one object changes, all its dependent objects get updated automatically.
// Step 1: Create Subject
class Subject {
constructor() {
this.observers = []; // list of observers
}
// Add observer
subscribe(observer) {
this.observers.push(observer);
}
// Remove observer
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
// Notify all observers
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
// Step 2: Create Observers
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received update: ${data}`);
}
}
// Step 3: Usage
const subject = new Subject();
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");
// Subscribe observers
subject.subscribe(observer1);
subject.subscribe(observer2);
// Notify all observers
subject.notify("New data available!");
// Output:
// Observer 1 received update: New data available!
// Observer 2 received update: New data available!
-
Promotes loose coupling
-
Easier to add/remove observers dynamically
-
Great for real-time applications
-
Can lead to complex debugging with many observers
-
Harder to trace changes in large systems