Singleton Factory patterns exampleFrom WikiJavabuy this book
This article shows how to create a class implementing the singleton and the factory patterns. Using the singleton/factory pattern you can wrap any class you want and have it generated as a singleton without modifying it. This may be very handy when you want to have an object shared between many threads and the object to be unique. For example a database connection or a shared object for exchanging messages between instances.
the article
The core class for this example, is the SingletonFactory. the core of the singleton pattern is the fact that the constructor is private. No one can instanciate the class, to obtain an instance of it you must always request it from the getSingletonFactory method. the getSingletonFactory method makes sure that only one instance of the class is returned at each request. static private LazySingletonFactory singletonFactory; private AClass aClass; // private constructor, we don't want the class to be instantiated from // others. private LazySingletonFactory() { this.aClass = new AClass(); } /** * Singleton Getter */ public static LazySingletonFactory getSingletonFactory() { if (singletonFactory == null) { synchronized (singletonFactory) { if (singletonFactory == null) { singletonFactory = new LazySingletonFactory(); } } } return singletonFactory; } The if in the getSingletonFactory method shown above is really to make sure that only one instance of the LazySingletonFactory class is generated and that's the only object one can obtain (I'll explain later why the class name is prefixed by the string "lazy"). The nice thing about the singleton of the LazySingletonFactory is that whenever you obtain the singleton object during the life of the JVM, the singleton will always contain the same instances of the objects. So if you implement the singleton class as to be a factory class as well, you will obtain the magic singleton factory class. This means that you will obtain always the same instance of the objects contained in the singleton. The method for implementing the factory pattern is simply a get method. Note that the aClass object is instanciated in a lazy way. the method is shown below: public AClass getAClass() { if (this.aClass == null){ synchronized(this) { if ( this.aClass == null ) { this.aClass = new AClass(); } } } return this.aClass; } Note: The getSingletonFactory method is static while the getAClass method is not. This is an important difference, because you have to be able to call the getSingletonFactory method without instantiating the class, to obtain an object. But you don't want to be able to call the getAClass if not on an object. This is an important detail in the implementation of this composite pattern. The singleton can be implemented lazily or not.
Note: In the most common situation in which you just access the SingletonFactory only for obtaining the singleton objects there's no substantial difference between the two methods. Also the contained class can be instantiated lazily. The preferred method in most of the cases would be the singleton instantiated 'normally' and the class instantiated lazily. As shown in the SingletonFactory class. I include also the SingletonClient class, which contains a main and shows the SingletonFactory class at work. SingletonClientpackage com.wikijava.patterns.singleton; import com.sun.corba.se.pept.transport.Acceptor; /** * this is the entry point class for the singleton Factory example. obtains * several times an object from the factory, and proves that it's always the * same object used. * * @author Giulio */ public class SingletonClient { /** * the main method * * @param args * no arguments */ public static void main(String[] args) { // obtain the factory, (this is the real singleton) SingletonFactory singletonFactory = SingletonFactory .getSingletonFactory(); // obtains the object from the factory. AClass aClassSingleton1 = singletonFactory.getAClass(); SingletonFactory singletonFactory2 = SingletonFactory.getSingletonFactory(); // obtains again the object AClass aClassSingleton2 = singletonFactory2.getAClass(); // the initial message System.out.println(aClassSingleton1.getMessage()); System.out.println(aClassSingleton2.getMessage()); // modifies the message in the first instance of the object aClassSingleton1.setMessage("modified"); //$NON-NLS-1$ // the message is changed also in the second instance because they are // the same object. System.out.println(aClassSingleton1.getMessage()); System.out.println(aClassSingleton2.getMessage()); } } LazySingletonFactory/** * */ package com.wikijava.patterns.singleton; /** * this class implements two patterns of Singleton and of Factory, the singleton * factory allows to transform in singleton any other class, without changing * it's code. * * This version implements the lazy behavior, it generates the singleton class * only at the very first call of the singleton * * @author Giulio */ public class LazySingletonFactory { static private LazySingletonFactory singletonFactory; private AClass aClass; // private constructor, we don't want the class to be instantiated from // others. private LazySingletonFactory() { this.aClass = new AClass(); } /** * Singleton Getter */ public static LazySingletonFactory getSingletonFactory() { if (singletonFactory == null) { synchronized (singletonFactory) { if (singletonFactory == null) { singletonFactory = new LazySingletonFactory(); } } } return singletonFactory; } public AClass getAClass() { return this.aClass; } } SingletonFactory/** * */ package com.wikijava.patterns.singleton; /** * this class implements two patterns of Singleton and of Factory, the singleton * factory allows to transform in singleton any other class, without changing * it's code. * * This version generates the singleton class in the moment the class is loaded. * * * @author Giulio */ public class SingletonFactory { static private SingletonFactory singletonFactory = new SingletonFactory(); private AClass aClass=null; // private constructor, we don't want the class to be instantiated from // others. private SingletonFactory() { //does nothing } public static SingletonFactory getSingletonFactory() { return singletonFactory; } /** * returns the AClass object contained in the singleton, the object is created lazily * * @return the "singletonized" class */ public AClass getAClass() { if (this.aClass == null){ synchronized ( this ) { if ( this.aClass == null ) { this.aClass = new AClass(); } } } return this.aClass; } } |
