2008-12-10 4 views
4

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

+0

Это не очень ясно. Можете ли вы дать нам пример того, что вы делаете * tyring *? – 2008-12-10 13:23:54

+0

@Bill Я думаю, что он все еще пытается решить http://stackoverflow.com/questions/355899/creating-singleton-factory вопрос, который он задал – 2008-12-10 13:27:37

ответ

4

Implementing the Singleton Pattern in Java: «... создать интерфейс для объектов, которые создают экземпляры класса 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

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

2

Singleton можно реализовать как:

public class Singleton { 

private static Singleton mInstance; 

private Singleton(){} 

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

} 

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

6

В этом примере, я считаю, вы хотели бы синхронизировать свой метод getInstance(), чтобы гарантировать, что два потока одновременно не вводят его. В противном случае два потока могут оказаться внутри блока, где создается одноэлемент, что очень проблематично. Единственная проблема с этим решением - вы платите премию за синхронизацию метода каждый раз, когда вызывается 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; 
} 

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

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

public static Singleton getInstance() 
{ 
    return mInstance; 
} 

Наиболее эффективный подход заключается в использовании блокировки с двойной проверкой, что вам нужно Java 1.5 или более поздней версии, чтобы надежно использовать в связи с различными реализациями энергозависимой ключевое слово в 1.4 или более старых виртуальных машинах (пожалуйста, обратитесь к разделу " Узоры Head First Design»глава 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; 
} 
0

Этот пример не является формальным Factory Pattern (GoF), но все же полезно, если вы используете его как Static Factory Method

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 

    } 
}