tags:

views:

1089

answers:

4

Is it possible to have a singleton in a factory method? I have many domains using the factory method. How do I work around with this. Please help me with an example.

+3  A: 

Implementing the Singleton Pattern in Java: "...create an interface for objects that create instances of the Singleton class. This is essentially a combination of the Abstract Factory, Factory Method and Functor patterns in the GoF book."

/**
 * An interface defining objects that can create Singleton
 * instances.
 */
public interface SingletonFactoryFunctor {
   /**
    * @return An instance of the Singleton.
    */
   public Singleton makeInstance();
}
mepcotterell
+3  A: 

You should call your Singleton getInstance() method from the factory method. The getInstance() logic should handle the details of returning the one instance of the Singleton.

Bill the Lizard
A: 

Singleton you can implement like:

public class Singleton {

private static Singleton mInstance;

private Singleton(){}

public static Singleton getInstance()
{
   if(mInstance==null){
      mInstance=new Singleton();
   }
return mInstance;
}

}

This class you can return in every Factory methode you want, like mepcotterell described before.

Markus Lausberg
+2  A: 

In this example, I believe you would want to synchronize your getInstance() method to ensure two threads do not simultaneously enter it. Otherwise two threads can end up inside the block where the singleton is instantiated which is very problematic. The only issue with this solution is you pay a premium for the synchronization of the method every time getInstance() is called. Example:

public static synchronized Singleton getInstance()
{
   // since whole method is synchronized only 1 thread can 
   // enter the following block ensuring only one instance 
   // is ever created. however we pay a synchronization
   // penalty every time this method is called.
   if(mInstance==null) { 
      mInstance=new Singleton();
   }
   return mInstance;
}

Alternatively you could also switch to use eager initialization of the singleton instance rather than lazy initialization if initializing is cheap which guarantees concurrency as well as not paying a synchronized penalty for invoking the getInstance() method. Example:

// no synchronization penalty, but penalty for eager init
private static Singleton mInstance = new Singleton();                          

public static Singleton getInstance()
{
    return mInstance;
}

The most optimized approach is to use double-checked locking, something you need Java 1.5 or newer to use reliably due to differing implementations of the volatile keyword in 1.4 or older JVMs (please refer to "Head First Design Patterns" chapter 5 p.182 published by O'Reilly Media, Inc. -- that is where I first read about this.) Example:

private volatile static Singleton mInstance;

private Singleton(){}

public static Singleton getInstance()
{
   if(mInstance==null) {
      synchronized (Singleton.class) { 
          // only pay synchronization penalty once
          if(mInstance==null){
              mInstance=new Singleton();
          }
      }
   }
   return mInstance;
}
Chris B.
No: double-locking idiom is no good, even if it can be implemented in 1.5 (prior to that, it couldn't be made to work).Reason is that you win nothing by doing it that way compared to the simpler synchronized example. Using volatile is no cheaper/faster, code is more verbose. So first 2 are better.
StaxMan