Метод синглтон-фабрики

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

10.12.2008 13:18:01
Это не очень понятно. Можете ли вы дать нам пример того , что вы Tyring делать?
Bill the Lizard 10.12.2008 13:23:54
@ Думаю, он все еще пытается решить вопрос stackoverflow.com/questions/355899/creating-singleton-factory, который он задал
Jacob Schoen 10.12.2008 13:27:37
Я рассчитываю немного прояснить, что означает «иметь синглтон», и «много доменов» помогут.
Nick Holt 10.12.2008 14:06:24
tiwari.vikash 30.07.2012 17:46:51
5 ОТВЕТОВ

«... создайте интерфейс для объектов, которые создают экземпляры класса 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();
}
4
6.01.2019 13:41:48

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

3
10.12.2008 13:22:56

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

public class Singleton {

private static Singleton mInstance;

private Singleton(){}

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

}

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

2
10.12.2008 20:03:25

В этом примере, я полагаю, вы захотите синхронизировать свой метод 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;
}
6
11.12.2008 00:28:26
Нет: идиома двойной блокировки не годится, даже если она может быть реализована в 1.5 (до этого она не могла работать). Причина в том, что вы ничего не выигрываете, делая это таким образом, по сравнению с более простым синхронизированным примером. Использование volatile не дешевле и не быстрее, код более многословен. Так что первые 2 лучше.
StaxMan 16.03.2009 18:05:42
@StaxMan это правильно, только если ресурс не оспаривается, в противном случае пример DCL значительно быстрее. Поэтому я думаю, что следует читать «первое - лучше, второе - хорошо, если вы не ожидаете раздоров». Я согласен с тем, что DCL не годится, если вам нужен ленивый init, лучше всего использовать метод lazy initialization holder.
tterrace 8.04.2013 20:05:04

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

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
    }
}
0
11.03.2020 20:30:06