Singleton Pattern
The Singleton pattern restricts a class to a single instance and provides a global access point to that instance.
Intent
Sometimes you need exactly one object to coordinate actions across the system — a configuration manager, a connection pool, a logger. The Singleton pattern guarantees that a class has only one instance and provides a well-known access point.
Structure
The pattern has three moving parts:
- Private constructor — prevents external code from calling
new. - Static instance field — holds the single object.
- Static accessor method — creates the instance on first call, then returns it.
Example in TypeScript
class Singleton {
private static instance: Singleton;
private constructor() {
// initialization logic
}
static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const a = Singleton.getInstance();
const b = Singleton.getInstance();
console.log(a === b); // true
When to Use It
- You need exactly one instance of a class accessible from a well-known access point.
- The single instance should be extensible by subclassing, and clients should be able to use the extended instance without modifying their code.
Common Real-World Uses
- Database connection pools
- Application configuration objects
- Logging services
- Hardware interface access
Trade-Offs
| Advantage | Disadvantage |
|---|---|
| Controlled access to sole instance | Hard to unit-test (global state) |
| Reduced namespace pollution | Can hide dependencies |
| Lazy initialization | Potential thread-safety issues |
Related Patterns
- Factory Method — can use Singleton to ensure only one factory exists.
- Abstract Factory — often implemented as a Singleton.
- Builder — can be combined with Singleton to reuse a complex build process.