Intent §
- Ensures that a class can be instantiated only once and enables a global access point to that instant
Implementation §
- Make the class constructor private
- Use a static method to return the instance
- On the very first call the static method will call the constructor
class Singleton {
private static instance: Singleton;
private constructor() { }
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public someBusinessLogic() {
// ...
}
}
function clientCode() {
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
if (s1 === s2) {
console.log('Singleton works, both variables are the same instance.');
} else {
console.log('Singleton failed, variables are different instances.');
}
}
clientCode();
public final class Singleton {
private static Singleton instance;
public String value;
private Singleton(String value) {
// The following code emulates slow initialization.
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
this.value = value;
}
public static Singleton getInstance(String value) {
if (instance == null) {
instance = new Singleton(value);
}
return instance;
}
}
public class DemoSingleThread {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance("FOO");
Singleton anotherSingleton = Singleton.getInstance("BAR");
System.out.println(singleton.value);
System.out.println(anotherSingleton.value);
}
}
// Output
// FOO
// FOO
Examples §
- Many printers but one printer spool
- one window-manager instance for an OS
- one file-logger instance to prevent concurrency issues
Pros §
- The object is initialized only on the first call
Cons §
- Violates Single responsibility principle
- Unit testing is harder as we need an innovative way to test the class having a private constructor
Nton §
N
instances of a class
- Use a static counter and an instance array
- Make sure it’s thread safe
- Helpful with load balancing