2014-05-18 11 views
20

Non capisco come implementare la versione Enum del modello Singleton. Di seguito è riportato un esempio di implementazione dell'approccio "tradizionale" utilizzando il modello Singleton. Vorrei cambiarlo per usare la versione Enum ma non sono sicuro di come.Singleton Pattern: Utilizzo di Enum versione

public class WirelessSensorFactory implements ISensorFactory{ 

    private static WirelessSensorFactory wirelessSensorFactory; 

    //Private Const 
    private WirelessSensorFactory(){ 
     System.out.println("WIRELESS SENSOR FACTORY"); 
    } 

    public static WirelessSensorFactory getWirelessFactory(){ 

     if(wirelessSensorFactory==null){ 
      wirelessSensorFactory= new WirelessSensorFactory(); 
     } 

     return wirelessSensorFactory; 
    } 

} 
+0

Cosa intendi per "versione enum"? – kviiri

+1

Un'altra forma di implementazione del pattern Singleton utilizzando un Enum, è stata introdotta in java 1.5 –

+0

grazie ora capisco cosa intendi. Prova questo link: http://stackoverflow.com/questions/18425693/how-does-an-enum-singleton-function – kviiri

risposta

30
public enum WirelessSensorFactory { 
    INSTANCE; 

    // all the methods you want 
} 

Ecco la tua Singleton: un enum con una sola istanza.

Si noti che questo singleton è thread-safe, mentre il tuo non lo è: due thread potrebbero entrambi andare in una condizione di competizione o un problema di visibilità ed entrambi creano la propria istanza del singleton.

+0

Grazie, Come utilizzerei questa classe in un metodo principale? –

+2

Come qualsiasi altra enumerazione: WirelessSensorFactory.INSTANCE.someMethod() –

+0

Sì, quindi solo una istanza della classe può essere utilizzata sempre, è una multiton implementata nello stesso modo? –

1

Si è spiegato qui: http://javarevisited.blogspot.sk/2012/07/why-enum-singleton-are-better-in-java.html Così, può essere semplice fatto come questo:

public enum EasySingleton{ 
    INSTANCE; 
} 

e anche con l'utilizzo di astratto modello di progettazione di fabbrica:

public class Singleton{ 
    //initailzed during class loading 
    private static final Singleton INSTANCE = new Singleton(); 

    //to prevent creating another instance of Singleton 
    private Singleton(){} 

    public static Singleton getSingleton(){ 
     return INSTANCE; 
    } 
} 
4

di riferimento online del Efficace Capitolo Java here.

public enum WirelessSensorFactory implements ISensorFactory { // change CLASS to ENUM here 

     INSTANCE; //declare INSTANCE of the Enum 

     //private static WirelessSensorFactory wirelessSensorFactory; 

     // Remove the private construct - it's Enum, 
     // so you don't need to protect instantiations of the class 
      //private WirelessSensorFactory(){ 
      // System.out.println("WIRELESS SENSOR FACTORY"); 
      //} 

     // You don't need to check if instance is already created, 
     // because it's Enum, hence you don't need the static var 
      //public WirelessSensorFactory getWirelessFactory(){ 
      // if(wirelessSensorFactory==null){ 
      //  wirelessSensorFactory= new WirelessSensorFactory(); 
      // } 
      // return wirelessSensorFactory; 
      //} 

     /* 
     * All other methods you need and 
     * implementation of all the Factory methods from your interface 
     */ 

} 

Usage:

WirelessSensorFactory.INSTANCE.<any public method> 
+0

Grazie, come utilizzerei questa classe in un metodo principale? –

+0

@ RNI2013 Ho incluso l'utilizzo di esempio. – hovanessyan

14

Il modello standard è quello di avere la vostra enum implementare un'interfaccia - in questo modo non è necessario esporre più della funzionalità dietro le quinte che si deve .

// Define what the singleton must do. 
public interface MySingleton { 

    public void doSomething(); 
} 

private enum Singleton implements MySingleton { 

    /** 
    * The one and only instance of the singleton. 
    * 
    * By definition as an enum there MUST be only one of these and it is inherently thread-safe. 
    */ 
    INSTANCE { 

       @Override 
       public void doSomething() { 
        // What it does. 
       } 

      }; 
} 

public static MySingleton getInstance() { 
    return Singleton.INSTANCE; 
} 
0

è molto più facile rispetto alla tutte le altre versioni creazione Singleton: -

public enum WirelessSensorFactory { 

     INSTANCE; 

     //private static WirelessSensorFactory wirelessSensorFactory; 

     //Private Const 
     //private WirelessSensorFactory(){ 

      //System.out.println("WIRELESS SENSOR FACTORY"); 

     // } 


     // public static WirelessSensorFactory getWirelessFactory(){ 

      //if(wirelessSensorFactory==null){ 

       // wirelessSensorFactory= new WirelessSensorFactory(); 
      // } 

      // return wirelessSensorFactory; 
     // } 

} 
-1

seguente è un esempio di classe di singlton,

public class SingletonClass { 
    private static SingletonClass singletonInstance = null; 

    private SingletonClass() {  
    } 

    public static SingletonClass getSingletonInstance() {  
     if(singletonInstance == null) { 
      synchronized (SingletonClass.class) { 
       if(singletonInstance == null) { 
        singletonInstance = new SingletonClass(); 
       } 
      } 
     } 
     return singletonInstance; 
    } 
} 

Questo frammento sarà allenamento in ambiente multithreading anche perché applica il blocco alla classe.

+0

Questo è sbagliato. Il modo in cui il codice è, funziona solo in sistemi CPU core SINGLE multithread. Nel sistema multicore questo metodo è difettoso. Non esiste un collegamento "succede prima" tra le scritture e le letture. – impeto

+0

Rendete singletonInstance volatile per garantire che succeda-before – Mitra

+0

Sì ... aveva bisogno di un oggetto volatile, privato volatile statico SingletonClass singletonInstance = null; –