Friday, October 5, 2012

Patron : Singleton


Singleton est un patron de programmation de type creation.

Il permet de s'assurer qu'il existe qu'une seule instance d'une classe.
Par exemple, dans une partie de jeu de role (Donjons et Dragons ou autre), il existe un seul maitre du jeu.
Alors si on tente de créer un programme, il serait intéressant de limiter le nombre de maitre de jeu à 1.

Les étapes:

  • créer un constructeur "private" car on ne veut pas de constructeur "public". Attention, quand on crée une classe en java sans constructeur, en fait il y en a un d'ajouter automatiquement qui est "public". Donc en créant notre constructeur "private", on override le constructeur "public"
  • créer une variable statique qui va detenir l'instance unique
  • créer une fonction qui retourne l'instance unique 



Jeu.java
public class Jeu {
 
 public static void main(String[] args) {
  Jeu jeu = new Jeu();
  jeu.jouer();
 }
 
 public Jeu() { }
 
 public void jouer() { 
  Singleton maitreDuJeu = Singleton.getInstance();
  
  System.out.println(maitreDuJeu.getCompteur());
  maitreDuJeu.setCompteur(23);
  System.out.println(maitreDuJeu.getCompteur());
  
  // Singleton autreMaitreDuJeu = new Singleton();
  // -> erreur de compilation car il n'y a
  //    pas de constructeur "public"
  
  Singleton autreMaitreDuJeu = Singleton.getInstance();
  // en fait c'est le meme objet (= meme instance)!
  System.out.println(autreMaitreDuJeu.getCompteur());
 }
}
Singleton.java
public class Singleton {

 private static final Singleton instanceUnique = new Singleton();
 private int compteur = 0;

 private Singleton() {
  // besoin d'avoir un constructeur
  // "private" pour empecher d'avoir
  // un constructeur "public"
 }

 public static Singleton getInstance() {
  return instanceUnique;
 }
 
 public int getCompteur() {
  return compteur;
 }

 public void setCompteur(int compteur) {
  this.compteur = compteur;
 }
 
}
Le résultat de ce programme sera:
0
23
23
L'objet autreMaitreDuJeu est le même que maitreDuJeu, donc c'est normal d'avoir 23 comme résultat.

Et sans l'utilisation du patron ?

Prenons le même code sans utiliser le patron Singleton et imaginons que 2 ans plus tard, quelqu'un doit le modifier.

 public void jouerSansPatronSingleton() {
//on utilise le constructeur publique
  Singleton maitreDuJeu = new Singleton();
  
  System.out.println(maitreDuJeu.getCompteur());
  maitreDuJeu.setCompteur(23);
  System.out.println(maitreDuJeu.getCompteur());
  
// 2 ans plus tard, quelqu'un ajoute ces lignes
// car il ne sait pas qu'il existe deja un objet
  Singleton autreMaitreDuJeu = new Singleton();
  System.out.println(autreMaitreDuJeu.getCompteur());
 }
Le résultat de ce programme sera:
0
23
0
Donc quand on veut s'assurer qu'il existe une seule instance d'une classe, le patron Singleton est très utile.

No comments: