Chapter 21: The Singleton Pattern and the Double-Checked Locking Pattern
Code Examples
TOC
TOC
TOC
TOC
Singleton makes objects responsible for themselves
The Singleton could be implemented in code as shown in Example 21-1. In this example, I create a method (getInstance) that will instantiate at most one USTax object. The Singleton protects against someone else instantiating the USTax object directly by making the constructor private, which means that no other object can access it.
Example 21-1: Singleton Pattern
TOP
public class USTax extends Tax {
private static USTax instance;
private USTax() {
}
public static USTax getInstance() {
if (instance== null) instance= new USTax();
return instance;
}
}
Singleton with polymorphism
Example 21-2: Singleton Pattern in the context of the e-commerce system
TOP
abstract public class Tax {
static private Tax instance;
protected Tax() {
}
abstract double calcTax(double qty, double price);
public static Tax getInstance() {
// use whatever rule you use to determine
// which tax object to use. For now,
// let's create a USTax object.
instance= USTax.getInstance();
return instance;
}
}
public class USTax extends Tax {
private static USTax instance;
private USTax() {
}
// Note in the following, I had to change USTax
// to Tax since I used the same "getInstance"
// name.public static Tax getInstance() {
if (instance== null) instance= new USTax();
return instance;
}
}
Example 21-3: Instantiation Only
TOP
public class USTax extends Tax {
private static USTax instance;
private USTax() {
}
public static Tax getInstance() {
if (instance== null) {
synchronized(this) {
if (instance == null) instance = new USTax();
}
}
return instance;
}
private synchronized static void doSync() {
if (instance == null)instance = new USTax();
}
}
A Solution for Java
It is not all that hard to fix this – not that I figured it out on my own. One solution is to take advantage of the class loader, as shown in Example 21-4.
Example 21-4: Instantiation Only
TOP
public class USTax extends Tax {
private static class Instance {
static final Tax instance= new USTax();
}
private static USTax instance;
private USTax() {
}
public static Tax getInstance() {
return Instance.instance;
}
}