2013-03-23 20 views
8

Come Bloch afferma al punto 3 ("far rispettare la proprietà Singleton con un costruttore privato o di un tipo enum") del Effective Java 2nd Edition, un tipo enum singolo elemento è il modo migliore per implementare un singleton. Sfortunatamente il vecchio modello di costruttore privato è ancora molto diffuso e radicato, al punto che molti sviluppatori non capiscono cosa sto facendo quando creo enum singletons.annotazioni per Java enum Singleton

Un semplice // Enum Singleton commento di cui sopra la dichiarazione della classe aiuta, ma lascia ancora aperta la possibilità che un altro programmatore potrebbe venire dopo e aggiungere una seconda costante al enum, rompendo la proprietà Singleton. Per tutti i problemi che l'approccio del costruttore privato ha, a mio avviso, è un po 'più autodocumentante di un enum singleton.

Penso che ciò di cui ho bisogno è un'annotazione che afferma sia che il tipo di enum è un singleton e assicura in fase di compilazione che all'enumerazione viene aggiunta una sola costante. Qualcosa del genere:

@EnumSingleton // Annotation complains if > 1 enum element on EnumSingleton 
public enum EnumSingleton { 
    INSTANCE; 
} 

Qualcuno ha eseguito un'annotazione di questo tipo per Java standard nelle librerie pubbliche? O è ciò che sto chiedendo impossibile sotto l'attuale sistema di annotazione di Java?

UPDATE

Una soluzione che sto utilizzando, almeno fino a quando decido di preoccuparsi in realtà con dolci le mie annotazioni, è quello di mettere @SuppressWarnings("UnusedDeclaration") direttamente di fronte al campo INSTANCE. Fa un lavoro decente di rendere il codice un aspetto distinto da un tipo enum semplice.

+1

Il modo migliore deve essere in primo luogo semplice e chiaro dal mio punto di vista. – kapand

risposta

2

Io non sono a conoscenza di una tale annotazione nei pubblici librerie Java, ma puoi definirti come un'annotazione del tempo di compilazione da utilizzare per i tuoi progetti. Ovviamente, è necessario scrivere un processore di annotazione e invocare in qualche modo lo (con ant o maven) per verificare le enumerazioni annate @EnumSingleton in fase di compilazione per la struttura prevista.

Ecco una risorsa su come scrivere e utilizzare compile time annotations.

3

Si può usare qualcosa di simile -

public class SingletonClass { 
    private SingletonClass() { 
     // block external instantiation 
    } 

    public static enum SingletonFactory { 
     INSTANCE { 
      public SingletonClass getInstance() { 
       return instance; 
      } 
     }; 

     private static SingletonClass instance = new SingletonClass(); 
     private SingletonFactory() { 
     } 

     public abstract SingletonClass getInstance(); 
    } 
} 

e si può accedere in qualche altra classe -

SingletonClass.SingletonFactory.INSTANCE.getInstance(); 
+0

Grazie! Questo è un approccio interessante per fondere i vantaggi dei costruttori privati. Certamente rende il fatto che è un singleton molto più ovvio. :) Un'altra cosa che mi viene in mente è di mettere un controllo sulla lunghezza di EnumSingleton.values ​​() nel costruttore predefinito privato di enum. Quindi posso almeno lanciare una RuntimeException se qualche persona incurante tenta di aggiungere un'altra costante all'enum ad un certo punto. –

+0

@AndrewBissell Penso che sia un candidato migliore per un test unitario in quanto i test unitari sono utili per descrivere il comportamento di una classe. – Jazzepi

+0

@Jazzepi Proprio come te! Ho ottenuto una bella traccia di stack con una riga "invokeExplosively" al suo interno quando ho provato a leggere la lunghezza di values ​​() prima che l'enum fosse stato inizializzato. :) Così tanto per quell'idea. –