Метод синглтон-фабрики - PullRequest
4 голосов
/ 10 декабря 2008

Можно ли иметь синглтон в заводском методе? У меня много доменов, использующих фабричный метод. Как мне обойти это. Пожалуйста, помогите мне с примером.

Ответы [ 5 ]

6 голосов
/ 11 декабря 2008

В этом примере, я полагаю, вы захотите синхронизировать свой метод getInstance (), чтобы два потока не одновременно вводили его. В противном случае два потока могут оказаться внутри блока, где создается экземпляр singleton, что очень проблематично. Единственная проблема с этим решением - вы платите премию за синхронизацию метода каждый раз, когда вызывается getInstance (). Пример:

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;
}

В качестве альтернативы вы также можете переключиться на использование быстрой инициализации экземпляра синглтона, а не на отложенную инициализацию, если инициализация дешевая, что гарантирует параллелизм, а также не платит синхронизированный штраф за вызов метода getInstance (). Пример:

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

public static Singleton getInstance()
{
    return mInstance;
}

Наиболее оптимизированный подход заключается в использовании двойной проверки блокировки, что необходимо для надежной работы с Java 1.5 или новее из-за различных реализаций ключевого слова volatile в 1.4 или более ранних версиях JVM (см. Главу 5 «Сначала шаблоны проектирования»). стр.182, опубликованная O'Reilly Media, Inc. - именно здесь я впервые прочитал об этом.) Пример:

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;
}
4 голосов
/ 10 декабря 2008

"... создайте интерфейс для объектов, которые создают экземпляры класса Singleton. По сути, это комбинация шаблонов Abstract Factory, Factory Method и Functor в книге GoF."

/**
 * An interface defining objects that can create Singleton
 * instances.
 */
public interface SingletonFactoryFunctor {
   /**
    * @return An instance of the Singleton.
    */
   public Singleton makeInstance();
}
3 голосов
/ 10 декабря 2008

Вы должны вызвать ваш метод Singleton getInstance() из фабричного метода. Логика getInstance() должна обрабатывать детали возврата одного экземпляра Singleton.

2 голосов
/ 10 декабря 2008

Синглтон вы можете реализовать как:

public class Singleton {

private static Singleton mInstance;

private Singleton(){}

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

}

Этот класс вы можете возвращать в любом заводском методе, который хотите, как в mepcotterell, описанном ранее.

0 голосов
/ 26 октября 2012

Этот пример не является формальным фабричным шаблоном (GoF), но все же полезен, если вы используете его как Статический фабричный метод

</p> <pre><code>abstract class Product { } class ConcreteProduct extends Product{ } class ProductSupportFactory { private static ProductSupportFactory instance = null; private ConcreteProduct product = null; static { instance = new ProductSupportFactory(); } private ProductSupportFactory() { product = new ConcreteProduct(); //object initialization } public static ProductSupportFactory getInstance(){ return instance; } public ConcreteProduct getProduct() { return product; } public void setProduct(ConcreteProduct product) { this.product = product; } } public class ProductConsumer { public static void main(String args[]){ //client ConcreteProduct uniqueInstance = ProductSupportFactory.getInstance().getProduct(); ConcreteProduct sharedInstance = ProductSupportFactory.getInstance().getProduct(); //same object hash } }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...