Aller au contenu principal

Singleton

Les design patterns20 min

Garantir une instance unique sans oublier le prix de l'état global.

Dans cette leçon

Le paramètre qui traverse tout

Un Singleton n'est pas un raccourci pour éviter des paramètres. Il impose une règle : cette ressource ne peut avoir qu'une instance.

Ici, un même ConnectionManager traverse SupportApp puis Dashboard. Ces deux classes ne l'utilisent pas. Seul le bouton final en a besoin.

Un second bouton contourne la chaîne avec new ConnectionManager(). Il écrit alors dans un autre journal. Le rapport principal oublie son événement.

SupportApp.java

Ce que le diff échange

Le transport mécanique du paramètre disparaît. En contrepartie, la dépendance n'apparaît plus dans les signatures. Aucun des deux choix n'est gratuit.

Imposer une instance unique

Trois éléments forment la recette enseignée. Les trois sont nécessaires.

  1. Créer l'instance dans la classe

    Le champ private static final INSTANCE contient la référence partagée.
  2. Fermer le constructeur

    Le constructeur private interdit tout new ConnectionManager() depuis une autre classe.
  3. Exposer un point d'accès

    getInstance() retourne toujours la même référence.
ConnectionManager.java

Le piège classique

Ajouter getInstance() sans rendre le constructeur privé ne garantit pas l'unicité. Un appelant peut encore créer une seconde instance.

Identité et état partagé

Deux variables peuvent désigner le même objet. Avec ==, vous vérifiez ici leur identité, pas seulement l'égalité de leur contenu.

Main.java

La mutation faite avec first est visible avec second, car il n'existe qu'un seul journal en mémoire. C'est utile pour une vraie ressource centrale. C'est aussi la source du danger : une modification locale peut affecter tout le programme.

Le compromis à défendre

Bon cas

  • • La ressource est unique par nature.
  • • Une configuration partagée reste surtout lue.
  • • Dupliquer la ressource produirait un état incohérent.

Mauvais cas

  • • Le partage est seulement plus pratique à court terme.
  • • Beaucoup de code modifie l'état global.
  • • Les tests doivent remplacer facilement la dépendance.
ChoixForceCoût
Objet transmis explicitementLa dépendance reste visible dans les signatures.Le paramètre peut traverser des classes qui ne l'utilisent pas.
SingletonUne seule instance et un accès central.Dépendance cachée, couplage et tests plus difficiles.

Quand ne pas l'utiliser

Si un objet ordinaire peut être créé une fois puis transmis seulement aux classes qui en dépendent, cette solution reste souvent plus explicite. Une instance partagée par convenance n'est pas forcément une instance unique par nature.

Vérifiez vos réflexes

Vérifiez vos réflexes

Une réponse par question. La correction apparaît tout de suite.

1. Quelle déclaration empêche une autre classe d'appeler new ConnectionManager() ?
2. a et b viennent de deux appels à getInstance(). Que vaut a == b ?
3. Pourquoi un new sauvage cassait-il le rapport de connexion ?
4. Quel cas justifie le mieux un Singleton ?
5. Quel coût reste après la refactorisation ?

Continuez le parcours

Centre de commandes

Rechercher une page et s'y rendre