Recipe 9.10 Enforcing the Singleton Pattern


Problem

You want to be sure there is only one instance of your class in a given Java Virtual Machine.

Solution

Make your class enforce the Singleton Pattern (see Design Patterns, page 127), primarily by having only a private constructor(s).

Discussion

It is often useful to ensure that only one instance of a class gets created, usually to funnel all requests for some resource through a single point. An example of a Singleton from the standard API is java.lang.Runtime ; you cannot create instances of Runtime, you simply ask for a reference by calling the static method Runtime.getRuntime( ). Singleton is also a good example of a design pattern because it can be easily implemented.

The easiest implementation consists of a private constructor and a field to hold its result, and a static accessor method with a name like getInstance( ) .

The private field can be assigned from within a static initializer block or, more simply, using an initializer. The getInstance( ) method (which must be public) then simply returns this instance:

// Simple demonstration Singleton instance public class Singleton {     private static Singleton singleton = new Singleton( );     /** A private Constructor prevents any other class from instantiating. */     private Singleton( ) {     }     /** Static 'instance' method */     public static Singleton getInstance( ) {         return singleton;     }     // other methods protected by singleton-ness would be here... }

Note that the method advocated in Design Patterns, of using "lazy evaluation" in the getInstance( ) method, is not necessary in Java, since Java already uses "lazy loading." Your Singleton class will probably not get loaded unless its getInstance( ) is called, so there is no point in trying to defer the singleton construction until it's needed by having getInstance( ) test the singleton variable for null and creating the singleton there.

Using this class is equally simple: simply get and retain the reference, and invoke methods on it:

public class SingletonDemo {         public static void main(String[] args) {                 Singleton tmp = Singleton.getInstance( );                 tmp.demoMethod( );         } }

Some commentators believe that a Singleton should also provide a public final clone( ) method (see Recipe 9.4) to avoid subclasses that "cheat" and clone( ) the singleton. However, on inspection, it is clear that a class with only a private constructor cannot be subclassed, so this paranoia does not appear to be necessary.

9.10.4 Variation

One variation is to make all methods static (as java.lang.Math does), but this works only if methods do not need to share state. You also lose the scalability that is inherent in the Singleton pattern: if you later need, say, 2 or 3 instances, you could easily change the getInstance( ) method to give out references to one of several, but you can't do that if all the methods are static.

See Also

The Collections class in java.util has methods singletonList( ), singletonMap( ), and singletonSet( ), which give out an immutable List, Map, or Set respectively, containing only the one object that is passed to the method. This does not, of course, convert the object into a Singleton in the sense of preventing that object from being cloned or other instances from being constructed, but it does qualify by providing a single access point that always returns the same instance.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net