“Il Singleton è un design pattern che ha lo scopo di garantire che di una determinata classe venga creata una e una sola istanza, e di fornire un punto di accesso globale a tale istanza.” (fonte Wikipedia).
Qui riporto la soluzione al problema proposta da Bill Pugh.
La struttura della classe Singleton è molto semplice e sfrutta alcune peculiarità del linguaggio Java. Ecco il codice:
class Prova { protected Prova() { } private static class ProvaHolder { private final static Prova INSTANCE = new Prova(); } public static Prova getInstance() { return ProvaHolder.INSTANCE; } }Il costruttore della classe è definito protected e questo impedisce che questo venga chiamato dall’esterno di tale classe. All’interno della classe Prova abbiamo definito una classe statica e privata, chiamata ProvaHolder, che al suo interno contiene il campo INSTANCE di tipo Prova; notiamo come INSTANCE sia dichiarato final static.
Quando il programmatore chiama il metodo statico getInstance la classe privata ProvaHolder viene “caricata” dalla JVM e viene allocato il suo campo statico INSTANCE attraverso la chiamata al costruttore protetto della classe Prova.
In questo modo siamo sicuri che della classe prova possa esserci una sola instanza, che è per giunta inizializzata in maniera lazy, ovvero solo al momento in cui viene effettivamente richiesta l’allocazione dell’oggetto.
Se ancora non è chiaro il funzionamento del pattern, ecco un esempio di cosa accade se creiamo due oggetti instanza della classe singleton appena dichiarata:
Prova p1 = Prova.getInstance(); Prova p2 = Prova.getInstance(); if(p1 == p2) System.out.println("uguali");Se provate ad eseguire questo codice, vedrete che la stringa “uguali” sarà stampata a schermo; il metodo getInstance ritorna sempre e solo un’unica instanza della classe Prova, quella creata al momento del caricamento da parte della JVM della classe privata ProvaHolder.
Cosa non si fa pur di non usare variabili globali 🙂
Comunque in java ho sempre aggirato il problema creando classi completamente statiche…evidentemente non sono mai andato a sbattere in un problema che richiedesse in pieno questo pattern
Questo è un esempio di come usando bene i costrutti che ti mette a disposizione un linguaggio sia possibile fare le cose in modo molto pulito. Il segreto sta tutto nel dichiarare il costruttore protected e la variabile INSTANCE come final
Basta, è ora di finirla con i singleton! Vatti a leggere qualcosa sulla dependency injection (http://en.wikipedia.org/wiki/Dependency_injection) e impara a usare guice (http://code.google.com/p/google-guice/) invece di diffondere design pattern vecchi come il cucco.
Ogni volta che viene scritto un singleton, dio uccide un gattino. Non contribuire anche tu a questa crudeltà.
Ciao 😉
Porca miseria è vero!
Per avere l’accesso lazy effettuavo il controllo null su una variabile statica della stessa classe! non avevo pensato alla classe interna!
Grazie!
Scusa, ma perché un’altra classe, statica per giunta?
public class Singoletto {
protected static Singoletto instance = null ;
protected Singoletto() {
// metodo costruttore
}
public static Singoletto getInstance() {
if (Singoletto.instance) return Singoletto.instance ;
else {
Singoletto.instance = new Singoletto() ;
return Singoletto.instance ;
}
}
}
Per me ha sempre funzionato…
In questa implementazione ci sono due problemi: prima cosa non è thread-safe (cosa che succede con la classe interna visto che la thread-safetyness è fornita dal linguaggio), seconda cosa non vedo synchronized sul getInstance, con la conseguenza che anche sotto la stessa jvm si potrebbero avere due istanze di singoletto (stessa jvm intendo che il singleton è ‘unico’ solo all’interno di un determinato “container” – classloader).
Ovviamente ho provato a formattarlo, ma wordpress non l’ha capito..