# Singleton (informatica)

Nella programmazione orientata agli oggetti, il singleton è uno dei design pattern fondamentali descritti dalla "Gang of Four" nel celebre libro Design Patterns.

## Scopo

Il singleton è un design pattern creazionale 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.

## Implementazione

L'implementazione più semplice di questo pattern prevede che la classe singleton abbia un unico costruttore privato, in modo da impedire l'istanziazione diretta della classe. La classe fornisce inoltre un metodo getter statico che restituisce l'istanza della classe (sempre la stessa), creandola preventivamente o alla prima chiamata del metodo, e memorizzandone il riferimento in un attributo privato anch'esso statico. Il secondo approccio si può classificare come basato sul principio della lazy initialization (lett. "inizializzazione pigra") in quanto la creazione dell'istanza della classe viene rimandata nel tempo e messa in atto solo quando ciò diventa strettamente necessario (al primo tentativo di uso).

### Esempio: Java

Il seguente frammento di codice descrive una classe strutturata secondo il pattern singleton nel linguaggio Java:
Bisogna precisare comunque che questo tipo di approccio risolutivo potrebbe presentare dei difetti (per esempio questa implementazione non è thread safe), infatti il progettista della classe che è chiamato tra l'altro a rispettare il pattern singleton, potrebbe, per esempio, erroneamente dichiarare all'interno della classe un metodo non statico con visibilità public che restituisca un'istanza di un nuovo oggetto della stessa classe, ed ecco che allora il vincolo viene violato in contraddizione a quanto sopra detto.
In definitiva questo significa che in realtà per adempiere pienamente bisogna gestire il tutto con il meccanismo delle eccezioni.
Si possono definire sotto altri metodi, che però non devono essere statici.

### Esempio: C++

Il seguente frammento di codice descrive una classe minimalista strutturata secondo il pattern singleton nel linguaggio C++:

### Esempio: C++11

Il seguente frammento di codice descrive una classe minimalista strutturata secondo il pattern singleton nel linguaggio C++11:

### Esempio: C#

Il seguente frammento di codice descrive una classe strutturata secondo il pattern singleton nel linguaggio C#:

### Esempio: Objective-C

Il seguente frammento di codice descrive una classe strutturata secondo il pattern singleton nel linguaggio Objective-C:

### Esempio: Swift

Il seguente frammento di codice descrive una classe strutturata secondo il pattern singleton nel linguaggio Swift:

### Esempio: PHP

Il seguente frammento di codice descrive una classe strutturata secondo il pattern singleton nel linguaggio PHP:

### Esempio: JavaScript Node.js

Il seguente frammento di codice descrive come creare un'istanza singleton di una classe usando JavaScript in Node.js:
A differenza degli altri linguaggi di programmazione, in JavaScript, non è possibile definire lo scope "privato" per funzioni e proprietà. Per applicare il pattern in Node.js bisogna agire con l'espediente usato in esempio.

## Implementazioni multi-thread

In applicazioni multi-thread l'utilizzo di questo pattern con la lazy initialization richiede un'attenzione particolare: se due thread tentano di eseguire contemporaneamente il costruttore quando la classe non è stata ancora istanziata, devono entrambi controllare se l'istanza esiste e soltanto uno deve creare la nuova istanza.

### Sincronizzazione esplicita

Il modo più semplice per implementare una versione thread-safe è quello di usare un meccanismo di sincronizzazione come quello fornito dalla parola chiave synchronized di Java. Tuttavia questo approccio è inefficiente: infatti la sincronizzazione è utile solo per la prima inizializzazione, e costituisce un inutile overhead nelle successive chiamate al metodo getter.

#### Esempio: Java
#### Esempio: C#

Ed eccone la traduzione in codice C#. Anche questa implementazione è thread-safe, e ugualmente inefficiente per l'utilizzo del lock sull'oggetto che funge da semaforo (verificando se l'istanza è null anche prima del lock, è possibile eliminare questa inefficienza):

### Sincronizzazione implicita

In alcuni linguaggi è possibile evitare l'overhead di sincronizzazione sfruttando quelle peculiarità della lazy initialization che consentono di assicurarsi la presenza del singleton in memoria all'atto del suo utilizzo. Le modalità specifiche possono variare da linguaggio a linguaggio; ad esempio, in Java è possibile sfruttare il fatto che l'inizializzazione di una classe e il suo caricamento in memoria, quando avvengono, sono operazioni thread-safe che comprendono l'inizializzazione di tutte le variabili statiche (attributi) della classe stessa.
Quello che segue è l'esempio più semplice, che tuttavia realizza la creazione dell'istanza al momento dell'inizializzazione della classe (per esempio, invocando un metodo statico della classe stessa). Questo approccio è adatto nei casi più semplici, o in quei casi in cui la lazyness non è necessaria; ad esempio, è sconsigliato in applicazioni in cui sono presenti numerosi singleton dall'inizializzazione "pesante" dotati di metodi o attributi statici che potrebbero essere acceduti in largo anticipo rispetto all'effettiva necessità d'uso del singleton in quanto tale (tipicamente, all'avvio dell'applicazione).

#### Esempio di inizializzazione lazy: Java

Un approccio che rimanda la creazione del singleton al suo effettivo primo utilizzo è stato presentato per la prima volta da Bill Pugh, e sfrutta appieno la lazy initialization: l'idea è quella di includere nella classe che implementa il singleton una classe contenitore avente, come attributo statico, una istanza del singleton stesso: il primo accesso a tale attributo statico (e la contestuale inizializzazione) verrà quindi effettuato durante l'inizializzazione della classe contenitore, e quindi sempre in modo serializzato. In questo modo l'istanza del singleton viene creata solo alla prima chiamata del metodo getter, e non prima.

### Esempi: Vb.Net
## Critiche

Alcuni autori hanno criticato il pattern singleton, osservando che, con opportune modifiche strutturali, una istanza singola può entrare più efficacemente a far parte dell'ambiente globale dell'applicazione.