Skip to content

Latest commit

 

History

History
129 lines (105 loc) · 3.7 KB

File metadata and controls

129 lines (105 loc) · 3.7 KB

Singleton

File Structure

📦 src/singleton
 ┣ 📜 singleton.ts
 ┣ 📜 README.md
📦 test/singleton
 ┣ 📜 singleton.test.ts

Test

npm run test:singleton

Breakdown

Key Points

  • ✅ Guarantees that only one instance of a class exists.
  • ✅ Provides a single point of access (usually through a static method).
  • ✅ Often implemented using lazy initialization (instance created only when needed).
  • ✅ Useful for managing shared resources, such as database connections, logging systems, or configuration settings.

Benefits

  • Controlled Access – Prevents multiple instances from being created accidentally.
  • Efficient Resource Management – Saves memory and improves performance by sharing resources.
  • Thread-Safe (if implemented correctly) – Avoids race conditions in multi-threaded environments.
  • Global Access Point – Ensures that different parts of an application use the same instance.

Drawbacks

  • 🚫 Tight Coupling – Since the instance is globally accessible, classes depending on the singleton become tightly coupled to it, reducing flexibility.
  • 🚫 Difficult to Test – Singleton objects introduce global state, making unit tests less predictable and harder to isolate.
  • 🚫 Hidden Dependencies – Since singletons are accessible anywhere, they hide dependencies, making it harder to track where changes affect the system.
  • 🚫 Concurrency Issues – In multi-threaded environments, improper implementation can lead to race conditions or performance bottlenecks.
  • 🚫 Harder to Scale – If an application grows beyond a single-machine setup, a singleton might not work well in a distributed system.
  • 🚫 Inflexibility – Once a singleton is implemented, changing or extending its behavior can be complex without modifying multiple parts of the application.

Example

Class Architecture

classDiagram
    class INotification {
        <<interface>>
        +send() void
    }

    class NotificationService {
        -static instance: NotificationService
        -constructor()
        +static getInstance() NotificationService
        +sendNotification(notification: INotification) void
    }

    INotification <|.. MockNotification
    INotification <|.. EmailNotification
    INotification <|.. SMSNotification
    NotificationService --> INotification : Uses

Loading

Code - Snippet

interface INotification {
  send(): void;
}

/**
 * Notification Service
 * 
 * @class NotificationService
 * @description A singleton class for sending notifications
 */
export class NotificationService {
  /**
   * Instance
   * 
   * @private
   * @static
   * @type {NotificationService}
   */
  private static instance: NotificationService;

  /**
   * Constructor
   * 
   * @private
   */
  private constructor() {
    console.log('NotificationService initialized');
  }

  /**
   * Get Instance
   * 
   * @static
   * @returns {NotificationService}
   */
  static getInstance(): NotificationService {
    if (!NotificationService.instance) {
      NotificationService.instance = new NotificationService();
    }
    return NotificationService.instance;
  }

  /**
   * Send Notification
   * 
   * @param {Notification} notification
   */
  sendNotification(notification: INotification): void {
    notification.send();
  }
}

(() => {
  // Step 5: Using the Singleton
  const notificationService1 = NotificationService.getInstance();
  const notificationService2 = NotificationService.getInstance();
})();