15 minlesson

Introduction to Singleton Pattern

Introduction to Singleton Pattern

Singleton ensures a class has only one instance while providing a global access point.

The Problem

Some resources should only have one instance:

  • Configuration managers
  • Connection pools
  • Logger instances
  • Rate limiters
typescript
1// Without Singleton - multiple instances cause issues
2const config1 = new Configuration();
3const config2 = new Configuration();
4config1.set('apiKey', 'key1');
5config2.set('apiKey', 'key2');
6// Which one is correct? Inconsistent state!

The Solution: Singleton

typescript
1class Configuration {
2 private static instance: Configuration;
3 private settings: Map<string, string> = new Map();
4
5 private constructor() {} // Private constructor
6
7 static getInstance(): Configuration {
8 if (!Configuration.instance) {
9 Configuration.instance = new Configuration();
10 }
11 return Configuration.instance;
12 }
13
14 get(key: string): string | undefined {
15 return this.settings.get(key);
16 }
17
18 set(key: string, value: string): void {
19 this.settings.set(key, value);
20 }
21}
22
23// Usage
24const config1 = Configuration.getInstance();
25const config2 = Configuration.getInstance();
26config1 === config2; // true - same instance

When to Use

  1. Shared resources - Database connections, caches
  2. Configuration - Global settings
  3. Logging - Single log destination
  4. Rate limiting - Track API calls globally

Criticisms and Alternatives

Problems with Singleton:

  • Global state makes testing harder
  • Hidden dependencies
  • Violates Single Responsibility Principle

Alternatives:

  • Dependency Injection (preferred)
  • Module-level instance
  • IoC containers

Summary

Use Singleton sparingly. Often Dependency Injection is a better solution for managing shared resources.