Singleton
Ensures a class has only one instance and provides a global access point to it.
Context
In your application, you need an object to orchestrate a shared resource—a logging connection, an in-memory cache, global configuration—and creating multiple copies would lead to inconsistencies.
Problem
- Ensure that a class has exactly one instance.
- Provide a global access point to that instance, without resorting to loose global variables.
Solution
Make the constructor private and expose a static method that always returns the same instance, creating it lazily the first time.
#Structure
- Private constructor.
- Static field to hold the unique instance.
- Static
Instancemethod that returns it.
#Example in C#
public sealed class Logger
{
private static readonly Lazy<Logger> _instance = new(() => new Logger());
public static Logger Instance => _instance.Value;
private Logger() { }
public void Log(string message) =>
Console.WriteLine(quot;[{DateTime.UtcNow:O}] {message}");
}
// Usage
Logger.Instance.Log("Application started");
Lazy<T>solves the lazy initialization problem and is thread-safe by default (ExecutionAndPublication).
When NOT to use it
- When you're only using it to avoid passing dependencies → you are hiding coupling. Prefer dependency injection.
- When testing: a Singleton complicates mocks. Encapsulate it behind an interface.
- In multi-tenant environments where you need an instance per context.
Tradeoffs
| Pro | Con |
|---|---|
| Ensures uniqueness | Hidden global state |
| Lazy initialization | Complicates unit tests |
| Clear access point | Implicit coupling to the caller |
#Variants
See the variants in the sidebar menu: thread-safe (manual) and enum-like readonly.
#creational #gof #instance #global