The Singleton Pattern: Intent
The Singleton Pattern: Intent
l Intent
é Ensure a class only has one instance, and provide a global point of access
to it
l Motivation
The é
é
Sometimes we want just a single instance of a class to exist in the system
For example, we want just one window manager. Or just one factory for a
family of products.
Singleton é We need to have that one instance easily accessible
é And we want to ensure that additional instances of the class can not be
Pattern created
/**
* Class Singleton is an implementation of a class that
* only allows one instantiation.
*/
public class Singleton {
l Consequences
// The private reference to the one and only instance.
é Benefits
private static Singleton uniqueInstance = null;
Ý Controlled access to sole instance
Ý Permits a variable number of instances // An instance attribute.
private int data = 0;
/**
l Here's a test program:
* Returns a reference to the single instance.
* Creates the instance if it does not yet exist. public class TestSingleton {
* (This is called lazy instantiation.)
*/ public static void main(String args[]) {
public static Singleton instance() { // Get a reference to the single instance of Singleton.
if(uniqueInstance == null) uniqueInstance = new Singleton(); Singleton s = Singleton.instance();
return uniqueInstance;
} // Set the data value.
/** s.setData(34);
* The Singleton Constructor. System.out.println("First reference: " + s);
* Note that it is private! System.out.println("Singleton data value is: " +
* No client can instantiate a Singleton object! s.getData());
*/
private Singleton() {}
1
Singleton Implementation Singleton Implementation
/**
l Here is Singleton with eager instantiation.
* Returns a reference to the single instance.
l We'll create the singleton instance in a static initializer. This is */
guaranteed to be thread safe. public static Singleton instance() {
return uniqueInstance;
/** }
* Class Singleton is an implementation of a class that
* only allows one instantiation. /**
*/ * The Singleton Constructor.
public class Singleton { * Note that it is private!
* No client can instantiate a Singleton object!
// The private reference to the one and only instance. */
// Let’s eagerly instantiate it here. private Singleton() {}
private static Singleton uniqueInstance = new Singleton();
// Accessors and mutators here!
// An instance attribute. }
private int data = 0;
l What if we want to be able to subclass Singleton and have the l Method 1: Have the MazeFactory instance() method determine
single instance be a subclass instance? the subclass to instantiate
l For example, suppose MazeFactory had subclasses /**
EnchantedMazeFactory and AgentMazeFactory. We want to * Class MazeFactory is an implementation of a class that
instantiate just one factory, either an EnchantedMazeFactory or * only allows one instantiation of a subclass.
*/
an AgentMazeFactory.
public abstract class MazeFactory {
l How could we do this? Several methods:
é Have the static instance() method of MazeFactory determine the particular // The private reference to the one and only instance.
subclass instance to instantiate. This could be done via an argument or private static MazeFactory uniqueInstance = null;
environment variable. The constructors of the subclasses can not be
private in this case, and thus clients could instantiate other instances of the // The MazeFactory constructor.
subclasses. // If you have a default constructor, it can not be private
// here!
é Have each subclass provide a static instance() method. Now the subclass protected MazeFactory() {}
constructors can be private.
2
Singleton With Subclassing Method 1 (Continued) Singleton With Subclassing Method 1 (Continued)
// Create the instance using the specified String name. l Note that the constructors of EnchantedMazeFactory and
public static MazeFactory instance(String name) {
if(uniqueInstance == null)
AgentMazeFactory can not be private, since MazeFactory must
if (name.equals("enchanted")) be able to instantiate them. Thus, clients could potentially
uniqueInstance = new EnchantedMazeFactory(); instantiate other instances of these subclasses.
else if (name.equals("agent"))
uniqueInstance = new AgentMazeFactory();
return uniqueInstance;
}
}
Design Patterns In Java
The Singleton Pattern Bob Tarr Design Patterns In Java
The Singleton Pattern Bob Tarr
13 14
l The instance(String) methods violates the Open-Closed Principle, l Method 2: Have each subclass provide a static instance method()
since it must be modified for each new MazeFactory subclass /**
* Class MazeFactory is an implementation of a class that
l We could use Java class names as the argument to the * only allows one instantiation of a subclass. This version
instance(String) method, yielding simpler code: * requires its subclasses to provide an implementation of
* a static instance() method.
public static MazeFactory instance(String name) { */
if (uniqueInstance == null) public abstract class MazeFactory {
uniqueInstance = Class.forName(name).newInstance(); // The protected reference to the one and only instance.
return uniqueInstance; protected static MazeFactory uniqueInstance = null;
}
// The MazeFactory constructor.
// If you have a default constructor, it can not be private
// here!
protected MazeFactory() {}
// Return a reference to the single instance.
public static MazeFactory instance() {return uniqueInstance;}
}
Design Patterns In Java
The Singleton Pattern Bob Tarr Design Patterns In Java
The Singleton Pattern Bob Tarr
15 16
Singleton With Subclassing Method 2 (Continued) Singleton With Subclassing Method 2 (Continued)