Design Patterns in JavaScript: Examples for Node.js

онлайн тренажер по питону
Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Design Patterns in JavaScript with Examples for Node.js



Design patterns are proven solutions to common development problems. In JavaScript, especially in the Node.js environment, they help create scalable, maintainable, and reusable code. In this article, we will cover four main patterns: Singleton, Factory, Observer, and Module, with practical examples.



1. Singleton Pattern



Singleton ensures that a class has only one instance and provides a global access point to it. In Node.js, this is often used for database connections or application configuration.



Singleton Implementation in Node.js



class Database {  constructor() {    if (Database.instance) {      return Database.instance;    }    this.connection = null;    Database.instance = this;  }

async connect(uri) { // Simulating a DB connection this.connection = `Connected to ${uri}`; console.log(this.connection); }

getConnection() { return this.connection; }}

// Usageconst db1 = new Database();const db2 = new Database();

console.log(db1 === db2); // true

db1.connect('mongodb://localhost:27017/myapp');console.log(db2.getConnection()); // "Connected to mongodb://localhost:27017/myapp"


When to use: Managing connection pools, global logger, cache systems.



2. Factory Pattern



Factory allows creating objects without specifying the exact class. It centralizes object creation logic, simplifying code maintenance.



Factory Implementation for Validators



class EmailValidator {  validate(value) {    return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value);  }}

class PhoneValidator { validate(value) { return /^\\+?[\\d\\s\\-()]{7,15}$/.test(value); }}

class ValidatorFactory { createValidator(type) { switch (type) { case 'email': return new EmailValidator(); case 'phone': return new PhoneValidator(); default: throw new Error('Unknown validator type'); } }}

// Usageconst factory = new ValidatorFactory();const emailValidator = factory.createValidator('email');

console.log(emailValidator.validate('test@example.com')); // trueconsole.log(emailValidator.validate('invalid')); // false


When to use: Creating complex objects, working with different data formats (JSON, XML, YAML), generating UI components.



3. Observer Pattern



Observer creates a subscription mechanism that allows one object (observers) to track changes in another object (subject). In Node.js, this pattern is built-in via the EventEmitter class.



Observer Implementation with EventEmitter



const EventEmitter = require('events');

class NewsPublisher extends EventEmitter { publishArticle(title) { console.log(`📰 Article published: ${title}`); this.emit('article', { title, date: new Date() }); }}

class Subscriber { constructor(name) { this.name = name; }

receiveArticle(article) { console.log(`🔔 ${this.name} received: "${article.title}"`); }}

// Usageconst publisher = new NewsPublisher();const subscriber1 = new Subscriber('Anna');const subscriber2 = new Subscriber('Ivan');

publisher.on('article', (data) => subscriber1.receiveArticle(data));publisher.on('article', (data) => subscriber2.receiveArticle(data));

publisher.publishArticle('Design Patterns in JavaScript');// Output:// 📰 Article published: Design Patterns in JavaScript// 🔔 Anna received: "Design Patterns in JavaScript"// 🔔 Ivan received: "Design Patterns in JavaScript"


When to use

Blogs

Book Recommendations