Singleton Pattern
The Singleton pattern ensures a class has only one instance and provides a global access point to it. Use it when you need exactly one object to coordinate actions across the system — like a configuration manager, logger, or connection pool.
Overview
The Singleton pattern restricts a class to a single instance and exposes a global access point to it. It is one of the simplest creational patterns, but also one of the most controversial because it introduces global state into a system. When used deliberately for resources that genuinely should exist only once — a configuration store, a logger, a database connection pool — it removes the noise of passing the same reference everywhere and guarantees consistency.
When to use it
- You need exactly one instance of a resource shared across the whole application (config, logger, cache).
- Creating the instance is expensive and you want to defer it until first use (lazy initialization).
- You want a single source of truth that callers can reach without dependency injection plumbing.
Example
class Logger {
private static instance: Logger;
private constructor() {}
static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
log(message: string) {
console.log(`[${new Date().toISOString()}] ${message}`);
}
}
Logger.getInstance().log("App started");Pros
- Guarantees a single instance and a single access point.
- Lazy initialization avoids paying the cost until the instance is actually needed.
- Replaces ad-hoc global variables with a controlled, encapsulated lifecycle.
Cons
- Introduces global state, which makes unit testing and parallelism harder.
- Hides dependencies — callers reach into the singleton instead of declaring what they need.
- Can become a bottleneck or memory leak if its lifetime is the whole process.