Le singleton est un Design Pattern de création qui permet de garantir qu’il ne sera possible de créer qu’une seule instance d’une classe donnée.
Exemple d’utilisation :
- un objet représentant un composant matériel de l'ordinateur qui doit être restreint à une unique instanciation pour éviter des conflits de gestions des ressources du composant.
- Connexion à une base de donnée : faire en sorte que le programme se connecte toujours à la même base.
- Une classe d'interface
Ce singleton est très utilisé !
Dans sa version minimale, le singleton s'écrit ainsi :
public final class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Posons le problème suivant : Mon programme contient un unique objet 'singleton' qui sera utilisé jusqu’à la fin du programme. Comment faire pour être sur qu’il soit créé et le rendre unique tout au long du programme ?
La première idée est la suivante : on créé un classe singleton "final" et on appel un objet au début de programme que l’on garde tout au long du programme.
On créé donc une classe singleton :
public final class Singleton {
public Singleton(){;)
// some things...
}
Et dans le main :
public class App {
public static void main(String[] args) {
Singleton instance;
// uses instance
}
}
Problèmes :
- chaque fonction/classe/structure devra faire appelle au singleton.
- On n’a une pseudo-unicité : rien empêche de créer d'autre singleton plus tard
- Comment rendre implicite l’utilisation du président – sans appel à chaque fonction ou classe ?
On pourrait définir une instance via une variable globale :
public final class Singleton {
public static Singleton instance = new Singleton();
public Singleton(){;)
// some things...
}
Et dans le main :
public class App {
public static void main(String[] args) {
//directement via le membre static
Singleton.getInstance();
}
}
Mais on voudrait que le singleton ne puisse pas être modifié au cours du programme, ce qui est possible ici.
Comment rendre l’objet global impossible à changer ?
On peut rendre privée la variable globale et créer une fonction getInstance() qui renvoie le singleton static. De plus cette fonction doit permettre de créer l'objer static uniquement en cas de besoin.
public final class Singleton {
private static Singleton instance = new Singleton();
public Singleton(){;)
private static final getInstance(){
if ( instance == null )
{
instance = new Singleton();
}
return instance;
}
}
Et dans le main :
public class App {
public static void main(String[] args) {
//directement via le membre static
Singleton.getInstance();
}
}
Mais là encore, rien interdit de créer un nouveau singleton...
Comment rendre impossible la création d’une autre classe ?
Pour cela, on peut rendre privé le constructeur.
public final class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){;)
private static final getInstance(){
if ( instance == null )
{
instance = new Singleton();
}
return instance;
}
}