Singleton
Concetto di Singleton
Singleton si riferisce a una classe che può creare un'unica istanza. Esempi tipici di Singleton includono oggetti senza stato o componenti di sistema univoci. Tuttavia, le classi Singleton presentano il problema di essere difficili da testare a meno che il tipo non sia definito come interfaccia e la sua implementazione sia definita separatamente.
Come creare un Singleton
Metodo con campo final statico pubblico
Il costruttore privato viene chiamato solo una volta durante l'inizializzazione di Elvis e garantisce che sia un'unica istanza in tutto il sistema. Tuttavia, è possibile chiamare il costruttore privato utilizzando AccessibleObject.setAccessible(), ma questo metodo di manipolazione tramite riflessione può essere bloccato lanciando un'eccezione quando viene creato il secondo oggetto.
- Vantaggi
- È chiaro dall'API che la classe è un Singleton.
- Conciso.
Metodo che fornisce un metodo factory statico pubblico
Anche questo metodo garantisce che sia un'unica istanza in tutto il sistema, a parte la manipolazione tramite riflessione. Cambia semplicemente il campo in privato e utilizza il metodo factory statico per restituire l'oggetto.
- Vantaggi
- È possibile modificare il Singleton senza modificare l'API.
- Ad esempio, il metodo factory statico può restituire istanze diverse per ogni thread.
- Se necessario, può essere modificato in un metodo factory Singleton generico.
- Il riferimento al metodo del metodo factory statico può essere utilizzato come provider.
- Ad esempio, invece di Elvis::getInstance, può essere utilizzato Supplier<Elvis>.
- È possibile modificare il Singleton senza modificare l'API.
Se non si prevede di utilizzare i vantaggi di cui sopra, è meglio utilizzare il primo metodo.
Metodo che utilizza un tipo di enumerazione
Il metodo più consigliato è quello che utilizza un tipo di enumerazione. Rispetto ai due metodi precedenti, è sicuro anche dagli attacchi di riflessione e il codice è più pulito. Inoltre, come spiegato più avanti, i due metodi precedenti presentano lo svantaggio di richiedere codice aggiuntivo durante la serializzazione.
Tuttavia, è necessario prestare attenzione al fatto che, sebbene il Singleton che si desidera creare possa ereditare un'interfaccia, non può ereditare una classe.
Precauzioni durante la serializzazione di una classe Singleton
Se si desidera serializzare una classe Singleton creata con il primo o il secondo metodo, è necessario non solo implementare Serializable, ma anche dichiarare tutti i campi di istanza come transient e sovrascrivere il metodo readResolve() e fornirlo.
Commenti0