Singleton Pattern
1. What is Singleton?
The Singleton Design Pattern means:
A class is allowed to create only one object during the entire lifetime of the application, and that same object is reused everywhere.
So instead of:
- Creating a new object every time
We:
- Create one object once
- Share it across the application
Think of it like:
- One central authority
- Everyone refers to the same source
2. Why Do We Need Singleton?
To understand why, first understand the problem.
Without Singleton (Problem)
In a large application (like a bank):
- Multiple services run at the same time
- Each service may create its own object
- Some objects are not meant to be duplicated
This leads to:
- Wasted memory
- Inconsistent data
- Unexpected behavior
- Performance issues
3. Example: Bank Configuration
A bank has:
- Interest rates
- Daily transaction limits
- Feature flags (enabled / disabled services)
These values:
- Are same for everyone
- Should be loaded once
- Should not change randomly
If every service loads its own configuration:
- One service may use old values
- Another may use new values
This causes business inconsistency.
π Singleton ensures one shared configuration object
4. Core Idea Behind Singleton (How It Works)
Singleton is based on three simple rules:
- No one should create the object directly
- Only the class itself creates the object
- Everyone accesses the same object
This is achieved by:
- Making the constructor
private - Storing the object in a
staticvariable - Providing a
staticmethod to access it
5. Simple Example (Easy to Understand)
public class BankConfig {
private static BankConfig instance;
private BankConfig() {
// private constructor
}
public static BankConfig getInstance() {
if (instance == null) {
instance = new BankConfig();
}
return instance;
}
}
What is happening here?
-
private constructorβ preventsnew BankConfig() -
static instanceβ shared across application -
getInstance()β controls object creation
6. Why This Simple Version Is NOT Enough
In real systems:
-
Many threads run in parallel
-
Two threads may enter getInstance() at the same time
-
Both may create objects
This breaks the only one instance rule β οΈ Especially dangerous in banking systems
7. Thread-Safe Singleton (Real-World Ready)
public class BankConfig {
private static volatile BankConfig instance;
private BankConfig() {}
public static BankConfig getInstance() {
if (instance == null) {
synchronized (BankConfig.class) {
if (instance == null) {
instance = new BankConfig();
}
}
}
return instance;
}
}
-
synchronizedβ only one thread enters at a time -
double checkβ avoids unnecessary locking -
volatileβ ensures all threads see the same object
This version:
-
Is safe
-
Is efficient
8. Best and Cleanest Singleton in Java (Enum)
public enum BankAuditLogger {
INSTANCE;
public void log(String message) {
System.out.println("AUDIT: " + message);
}
}
Enum = Singleton ONLY if it has exactly ONE enum constant
β NOT Singleton
public enum BankRole {
ADMIN,
CASHIER,
MANAGER
}
Why Enum Singleton is Preferred
-
Java guarantees only one enum instance
-
Thread-safe by default
-
Safe from reflection & serialization issues
-
Very little code
π Many senior developers prefer this approach
9. Singleton in Spring Boot
In Spring Boot:
@Service
public class TransactionService {
}
By default:
-
Spring creates only one instance
-
Manages lifecycle for you
So:
-
You rarely write Singleton manually
-
You rely on Dependency Injection
π Singleton pattern is still important to understand, not always to implement
10. Alternatives to Singleton (Modern Approach)
Dependency Injection (Preferred)
Instead of:
BankConfig.getInstance();
We use:
@Autowired
private BankConfig bankConfig;
Why this is better:
-
Easy to test
-
Loose coupling
-
Cleaner design
11. When NOT to Use Singleton
Avoid Singleton when:
-
Object holds user-specific data
-
Multiple configurations are required
-
Unit testing becomes hard
-
Global state causes hidden bugs
Singleton is powerful, but dangerous if misused.
12. Summary
-
Singleton controls object creation
-
Thread safety depends on implementation
-
Enum Singleton is safest
-
Spring beans are singleton by default
-
Overuse of Singleton is considered a design smell
Singleton ensures a single shared instance, but in modern Spring applications, dependency injection is preferred over manual Singleton implementation.