Posted By : Mohd
Node.js provides a scalable and efficient platform for highly efficient web and mobile app development. As the usage of Node.js for building backend applications is increasing day by day, it becomes crucial to adopt best practices and design patterns to ensure maintainability, scalability, and code reusability. In this blog post, we will be looking at some of the design patterns that can be implemented to obtain maintainability, scalability, and code reusability.
In the singleton design pattern, we make sure that a class has only one instance which is available globally for a whole application. This design pattern can be used when there is a need to control access to some shared resources eg- a database connection or a file. By using this pattern you can avoid unnecessary duplication and improve the efficiency of your application.
Also, Explore | Essentials of Efficient UI/UX Design in Mobile App Development
Below is an example of the singleton pattern for a database connection. In this example class, "DatabaseConnection" follows the singleton design pattern and maintains only one instance of the database connection, whenever this class is instantiated, first it checks if an instance is already present, if not then only it creates a new connection to the database otherwise it just returns the already available instance.
/**
* Singleton Pattern - Representing a class for Database connection
*/
class DatabaseConnection {
constructor(str) {
// check for instance
if (!DatabaseConnection.instance) {
this.connection = // create database connection
this.testStr = str
DatabaseConnection.instance = this;
}
// return instance
return DatabaseConnection.instance;
}
}
// create instance of class
const dbInstance1 = new DatabaseConnection("1");
const dbInstance2 = new DatabaseConnection("2");
console.log(dbInstance1.testStr)
console.log(dbInstance2.testStr)
Output of the above code:
1
1
The Middleware pattern is a key element in Node.js frameworks like Express. It involves a chain of functions that process an incoming request and response. Each middleware function has access to the request, response objects, and the next middleware function in the stack. This pattern is excellent for handling tasks such as authentication, logging, and error handling in a modular and reusable way.
You may also like | Native vs. Hybrid vs. Web | Choosing Mobile App Development
Below is an example of a chain of responsibility pattern implemented using the middleware functionality in Node.js. The code defines two middleware functions "middleware1" and "middleware2" which are used by the "app". Whenever a request comes to our "app" first it passes through "middleware1" and then through "middleware2" before moving to the business logic.
/**
* Middleware Pattern - Representing middleware usage in Node.js
*/
// First middleware
const middleware1 = (req, res, next) => {
// perform some tasks
console.log("Inside middleware 1");
next();
};
// Second middleware
const middleware2 = (req, res, next) => {
// perform some tasks
console.log("Inside middleware 2");
next();
};
app.use(middleware1);
app.use(middleware2);
Output of the above code:
Inside middleware 1
Inside middleware 2
The Facade pattern provides a simple interface to a complex system, hiding its complexities. In Node.js, this can be applied to create a unified API for different modules or subsystems. By doing so, developers can interact with a simplified interface while the underlying complexities are managed behind the scenes.
Also, Read | Cloud-based App Development | A Quintessential Guide
Below is an example of facade pattern implementation using a payment gateway class. "PaymentGateway" is a class that implements the functionality of handling payments internally, i.e., the complex processes of verifying a payment or processing the transaction are hidden from the client code, this makes the implementation more robust.
/**
* Facade Pattern - Representing a Payment Gateway that hides its complexities
*/
class PaymentFacade {
processPayment(amount) {
// Create an instance of payment gateway
const paymentGateway = new PaymentGateway();
// Use the payment gateway to verify payment without knowing the underlying logic
paymentGateway.verifyPayment();
paymentGateway.processTransaction(amount);
return 'Payment successful';
}
}
In the Observer design pattern an object, known as the subject (publisher), maintains a list of its dependents (subscriber or observer) who subscribe to events from the publisher, they are then informed about these events via different methods from the publisher. This pattern establishes a one-to-many relationship between the subject and its observers, allowing multiple objects to react to the changes in another object without being tightly coupled.
In the below example, the "NewsAgency" is the subject or publisher which publishes news to it's observers, and "NewsReader" instances are observers. When the "NewsAgency" updates its news, all registered observers are notified and respond accordingly.
/**
* Observer Pattern - Representing a News Agency that published news to News Readers
*/
// Subject or Publisher
class NewsAgency {
constructor() {
// List of observers for this news agency
this.observers = [];
this.news = null;
}
// Add observers
addObserver(observer) {
this.observers.push(observer);
}
// Remove observer
removeObserver(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
}
// Set News
setNews(news) {
this.news = news;
// Notify the observers about the News
this.notifyObservers();
}
// Notify the observers about the News
notifyObservers() {
this.observers.forEach((observer) => observer.update(this.news));
}
}
// Observer or Subscriber
class NewsReader {
constructor(name) {
this.name = name;
}
update(news) {
console.log(`${this.name} received news: ${news}`);
}
}
// Instance of Publisher
const bbc = new NewsAgency();
// Instances of Subscribers
const john = new NewsReader('John');
const alice = new NewsReader('Alice');
// Add subscirbers to publisher
bbc.addObserver(john);
// Set News which also notifies the subscribers
bbc.setNews('Breaking News: Design patterns in Node.js');
Output of the above code:
John received news: Breaking News: Design patterns in Node.js
After looking at the above design patterns, now it is time to understand that before applying any design pattern to your application it's important to understand the context, requirement, and scalability of your application and then decide which pattern or a combination of patterns can help you develop the application in a more modular way. In case if you are looking for web and mobile app development, our skilled web and mobile app developers can help you get started quickly.
November 22, 2024 at 10:32 pm
Your comment is awaiting moderation.