Evaluate real Java Singleton use cases carefully so singularity reflects the model rather than convenience-driven global access.
Valid singleton use case: A situation where one process-wide instance models a real architectural or runtime boundary rather than just making access convenient.
Most singleton examples in old design-pattern material are too generous. They make the pattern look appropriate anywhere shared access exists. In modern Java systems, the stronger question is whether singularity is part of the model or merely a shortcut.
Singleton can be reasonable for:
In these cases, one instance reflects a real process-level concern.
Singleton is often a poor fit for:
If the main justification is “many classes need this,” that is usually not enough.
When reviewing a candidate singleton, compare it against:
Very often, one of those gives the same operational behavior with cleaner boundaries.
1public enum AppSettings {
2 INSTANCE;
3
4 private String region = "ca-central-1";
5
6 public String region() {
7 return region;
8 }
9}
This might be fine if the application truly has one immutable startup configuration snapshot and the lifecycle is obvious.
1public final class Services {
2 private static final Services INSTANCE = new Services();
3
4 private UserService userService;
5 private BillingService billingService;
6 private EmailService emailService;
7
8 public static Services getInstance() {
9 return INSTANCE;
10 }
11}
This is usually a smell. It is drifting toward service locator, hidden dependencies, and test friction.
When reviewing singleton use cases, ask:
A valid singleton use case should survive comparison against cleaner alternatives, not just sound familiar from pattern catalogs.