Una classe statica con un carico di variabili statiche è un po 'un trucco.
/**
* Grotty static semaphore
**/
public static class Ugly {
private static int count;
public synchronized static void increment(){
count++;
}
public synchronized static void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized static boolean isClear(){
return count==0;
}
}
Un singleton con un'istanza reale è migliore.
/**
* Grotty static semaphore
**/
public static class LessUgly {
private static LessUgly instance;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( instance==null){
instance = new LessUgly();
}
return instance;
}
public synchronized void increment(){
count++;
}
public synchronized void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized boolean isClear(){
return count==0;
}
}
Lo stato è SOLO nell'istanza.
Quindi il singleton può essere modificato in seguito per eseguire operazioni di pooling, istanze locali di thread, ecc. E nessuno dei codici già scritti deve essere modificato per ottenere il vantaggio.
public static class LessUgly {
private static Hashtable<String,LessUgly> session;
private static FIFO<LessUgly> freePool = new FIFO<LessUgly>();
private static final POOL_SIZE=5;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( session==null){
session = new Hashtable<String,LessUgly>(POOL_SIZE);
for( int i=0; i < POOL_SIZE; i++){
LessUgly instance = new LessUgly();
freePool.add( instance)
}
}
LessUgly instance = session.get( Session.getSessionID());
if( instance == null){
instance = freePool.read();
}
if( instance==null){
// TODO search sessions for expired ones. Return spares to the freePool.
//FIXME took too long to write example in blog editor.
}
return instance;
}
È possibile fare qualcosa di simile con una classe statica ma ci sarà un sovraccarico per chiamata nell'invio indiretto.
Puoi ottenere l'istanza e passarla a una funzione come argomento. Ciò consente al codice di essere indirizzato al singleton "giusto". Sappiamo che ne avrai bisogno solo uno ... finché non lo fai.
Il grande vantaggio è che i singleton con stato possono essere protetti dai thread, mentre una classe statica no, a meno che non venga modificata in modo che sia un singleton segreto.